Series "Developing an app with Dry-rb"
  1. What is dry-rb and how it might help solve problems with a Rails app
  2. How to launch an app with dry-system
  3. How to use Command pattern with the help of Dry-transaction

What is dry-rb and how it might help solve problems with a Rails app

I work for a startup. We are developing the most profitable mining pool with a smart profit-switching algorithm. The pool is written with Go as well as Ruby for internal services. We use microservice architecture and the apps are running within the containers. We a use TDD system even though our project is only a startup yet: weprefer to sleep less, but peacefully. The code quality is very important for us.

Why doesn’t Rails suit our needs?

The more services we introduced, the more we realized that Rails causes more problems than it solves despite being simple and offering great development speed. Here are some of the issues we faced.

Overly complicated architecture

First of all, our services look like simple programs, not like common Rails apps. The typical tasks are counting statistics, monitoring a blockchain network, calculating the users’ awards and sending transactions. One of the interfaces provided by API is, for example, a list of a (particular) user’s transactions. When we used Rails, in every folder there was like some another world. It was mostly acceptable, but we couldn’t help thinking that something was amiss.

Unfriendly multithreading

The other issue we came across with was asynchrony. We use threads a lot, so we got ‘autoload’ errors each time we didn’t preload the whole app. That wasn’t a big deal and we could always preload the app in the test environment. But to my mind the problem like that shouldn’t have existed in the first place. Threads may keep you busy without any gimmicks, anyway.

Unused dependencies

We can’t help but mention the resulting size of an app. Now it takes us only 50 seconds to deploy the new version on stage from the last push to master. It’s enough to run the tests, build and send the image to the registry. The same cycle took us 4 minutes before. Another advantage is that tests and console are now loaded in a second. This turned out to be a very pleasant small thing for our everyday routine.

High memory usage

At some point we realized that we didn’t have enough memory for our purposes. We have two worker threads for each service, and eventually it turned out to be rather RAM consuming. Now our services consume 8 times less memory on average than they did while we used to work with Rails.

How did we solve our problems?

Having kept all of the above and many more in mind, we decided to move to the dry-rb stack. We still use Rails, but for API-heavy services only, since they might take too much time to rewrite. We don’t think that Rails is dead, it’s just not suitable for our purposes. The members of the dry-rb community are working on lots of gems which, in their opinion, might help to create better apps. The gems are all tailored to solve some specialized problems and can be integrated into an existing app. The list of gems the community is working on can be found on its GitHub page. Nowadays we use most of those gems for our projects: dry-system, dry-web, dry-transaction, dry-validation, dry-types, dry-struct, dry-monads. With their help we solved the problems we’ve described below, but that’s not it. The apps are now less memory consuming, divided into completely encapsulated components and easier to test. All the team members enhanced their expertise and became more deeply involved in the project. In my opinion, the latter is highly essential, since the employees’ enthusiasm guarantees good atmosphere in any office. We’re going to talk more about how we use these solutions for our projects in the next articles of this series.