Failure Management, Fallbacks, Exponential backoff, Tools and Patterns

When designing modern applications on microservices architecture and systems based on cloud solutions such as AWS, Azure, or Google Cloud imply the need to handle expected failures.

How to handle failures?

  1. Restarting the code in the current thread runtime
  2. Retry execute in background jobs

Retry failed code

We can represent the simplest retry in runtime as a rescue block and variable with a count of executed retries.

Also Ruby has built-in retry keyword, an example can be changed in the next way:

  1. Any application-level error should be a child of StandardError, for e.g. ApiError = Class.new(StandardError)
  2. List of handled errors should be specified in rescue, or at least rescue StandardError =>…


How to manage encrypted keys for different environments

There are two most popular ways to manage secrets in your application.

  1. Encrypted file with secrets. Best choice for a single monolith application. There’s no need for additional software, just keep your encrypted data in the app repository and move decrypt key under git ignore.
  2. Centralized storage. For large and complex systems it’s better to use dedicated storage for all services and provide an interface for them. Vault is a cool example of this kind of solution.

In this article, I want to talk about the first approach.

Encrypted secrets were first introduced in Rails 5.1. Rails store secrets in config/credentials.yml.enc by default. For applications created prior to Rails 5.2, we’ll automatically generate a new
credentials file in config/credentials.yml.enc


A tool for monitoring SQL queries in Rails

Get notified about slow queries

In the early stages of development, it may be useful to identify slow queries in time (when you don’t have a paid APM). QueryTrack helps to get notified about slow queries with related data: duration and backtrace.

https://github.com/kirillshevch/query_track

Installation

Add this line to your application’s Gemfile and then execute bundle install:

gem 'query_track'

To start receiving information about requests you need to createconfig/initializers/query_track.rb where there is a time limit that is specified in seconds and an output channel (for example console logs):

QueryTrack::Settings.configure do |config|
config.duration = 0.5
config.logs = true
end
Image for post
Image for post

Configuration

You won't get any notifications without setting the max duration of an SQL query. These settings will show at what point requests are considered to be slow. …


Publish/Subscribe Pattern with Message Brokers and usage of core concepts. Asynchronous execution of the application parts.

One of the tools that are rarely covered in the Ruby/Rails world are the message brokers (probably because they mostly written in Java). Everyone are familiar mostly with background jobs processing, but message brokers offer a more flexible approach to asynchronous execution. For example, you can create a message from one application and process it in another and continue executing without waiting for the response.

Some benefits that you get at the architectural level:

Fault Tolerance, Guaranteed delivery, Asynchronous communication(through Publish/Subscribe pattern), Loosely coupling, etc.

One of the messaging brokers that I used is ActiveMQ. ActiveMQ provides most of these features and I will consider building communication using this broker as an example. …


The main purpose of caching is making the application work faster. But also this mechanism can help to more flexibly manage data, a good example is session management.

Image for post
Image for post

Redis cache store

Rails 5.2 introduced built-in Redis cache store, which allows you to store cache entries in Redis.

To use Redis as a Rails cache store, use a dedicated cache instance that’s set up as an LRU (Last Recently Used) cache instead of pointing the store at your existing Redis server, to make sure entries are dropped from the store when it reaches its maximum size.

The Redis store works with the Redis gem and hiredis, as well as providing support for a number of configuration options, like setting one or multiple remote servers.

Usage

To get started, add the redis gem to your…


Writing jobs, testing, pros and cons of this approach.

Sucker Punch — a single-process Ruby asynchronous processing library that runs with your existing app’s process.

Gem is built on top of concurrent-ruby and have no dependencies with any data storage, what is both an advantage and a disadvantage.

Running in the application process really simplifies the deployment process, but If the web processes are restarted with jobs remaining in the queue, they will be lost. …


Module bundling, Loaders, Plugins, Babel

Webpack is a module bundler for modern JavaScript applications. The import and export statements have been standardized in ES2015. They are not supported in browsers yet, but webpack does support them out of the box. But actually it’s more powerful tool which can help us build whole our front-end.

Installing

Let’s start with initializing package.json by using npm init command.

Installing globally locks you down to a specific version of webpack and could fail in projects that use a different version. Therefore, we will install it locally.

npm install --save-dev webpack

Webpack will be added to devDependencies

Command Line Interface (CLI)

Because we are installing webpack locally we have to run it through npm…


Using Git hooks to control code quality for Ruby, Rails and Chef

What is Linter?

Linter is a static analysis tool such as RuboCop. It checks the written code and makes suggestions based on pre-defined rules by community-driven coding style guides and common idioms.

Most definitions of linter default behavior can be changed for the needs of your team and project via various configuration options.

Why linting and following style guides is important?

There are many reasons to lint the code:

  1. It maintains code consistency
  2. It helps catch unnecessary code
  3. It helps avoid conflicts between developers and also to remember about the conventions
  4. It helps optimize performance and avoid problems with security

Don’t forget to lint with Git hooks and Overcommit

Image for post
Image for post

Git hooks are scripts that execute before or after actions such as: commit, push, and receive. …


Saving time by automating routine deployment tasks

Why do we need automation?

Developers often save time on automation of the deployment process at the beginning of a project. Therefore, some of developers manually start the deployment. As the project becomes larger and the team grows, more features and fixes are released every day. Deployment takes a huge amount of precious time and distracts developers from working on important tasks like reviewing new versions or showing new features or fixes for clients.

Continuous Deployment

Continuous Delivery is a software development practice that allows for building software in such a way that the new update can be released any time.

CircleCI

The best practice is to automatically run the command for deployment after successful build passing. CircleCI makes it easy to configure your workflow and push the project to the deployment host. With CircleCI, each successful build of your code is automatically delivered to staging, production or any other stage you require to deliver your application. After the successful (or failed) build passing and deployment you receive an email notification. …


Cloud platforms vs dedicated server

Every developer is looking for a right way to deploy applications to production. Often, the question of the deployment is delayed at a later time, and it’s well known that many applications do not launch in production and developers just use solutions like Heroku for staging or demo servers. Cloud platforms are easy to use, but they are expensive and not so configurable, unlike your own VPS.

Server configurations management

The most popular tools for this which are frequently used in the Ruby world are Chef and Chef Solo.

With Chef you can define the steps required to configure a server to fulfill a “role”, for example a Rails application server or a database server and then apply combinations of these roles to a particular remote machine. …

About

Kirill Shevchenko

Software Engineer. Interested in Full-Stack Development and DevOps.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store