Running with Ruby

Tag: Rails (page 2 of 58)

Errbit + HTTPS: Setting up Errbit reporter (Airbrake v5 gem) to work with self-signed HTTPS certificate

Note: If you’re using old Errbit version (0.2.0, 0.4.0) and an old Airbrake version (v4) please refer to this manual to make it work with self-signed certificates.

Having an error catcher like Errbit behind SSL is generally a good idea. Especially when Errbit is hosted on a different server than you application (for example when you manage multiple apps with one Errbit instance). In many cases you will have a self-signed certificate (why would you pay for a cert for internal tool). If you try to use it with Airbrake, you will see following error:

Airbrake:
  HTTP error: SSL_connect returned=1 errno=0 state=unknown state: certificate verify failed

Unfortunately, global SSL certificates verification disabling hack (solution that used to work with Airbrake notifier v4) won’t work:

# No longer working!
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE

Luckily, Airbrake notifier is written pretty well, so hacking it (and disabling per request SSL certificate verification) is not hard at all. Here’s a full code you need to place in config/initializers/errbit.rb to make it work:

module Patches
  module Airbrake
    module SyncSender
      def build_https(uri)
        super.tap do |req|
          req.verify_mode = OpenSSL::SSL::VERIFY_NONE
        end
      end
    end
  end
end

Airbrake::SyncSender.prepend(::Patches::Airbrake::SyncSender)

After that (and configuring Airbrake notifier), you can test it out like this:

Airbrake.notify :test

Integrating Trailblazer and ActiveRecord transactions outside of a request lifecycle

When you use Ruby on Rails with ActiveRecord, you can get used to having separate transaction on each request. This is valid also when using Trailblazer (when inside of a request scope), however Trailblazer on its own does not provide such functionality. It means that when you’re using it from the console and/or when you process stuff inside background workers, you no longer have an active transaction wrapping around an operation.

This behavior is good most of the time. Since background tasks can run for a long period of time, there might be a risk of unintentional locking a big part of your database. However, sometimes you just need to have transactions.

In order to provide this feature for each operation, we will use a concern that will include that logic. We will also make it configurable, so if we inherit from a given operation, we will still have an option to disable/enable transaction support based on the operation requirements.

The code itself is pretty simple – it will just wraps around a #run method of the operation class with a transaction (as long as transaction support is enabled). Note, that by default transactional flag is set to false.

module Concerns
  module Transactional
    extend ActiveSupport::Concern

    included do
      class_attribute :transactional

      self.transactional = false
    end

    def run
      if self.class.transactional
        self.class.transaction do
          super
        end
      else
        super
      end
    end

    class_methods do
      def transaction
        ActiveRecord::Base.transaction do
          return yield
        end
      end
    end
  end
end

In order to use it, just include it into your operation:

class ApplicationOperation < Trailblazer::Operation
  # Including on its own won't turn transactions on
  include Concerns::Transactions
end

class DataOperation < ApplicationOperation
  # This operation will have a single transaction wrapping it around
  self.transactional = true
end
Olderposts Newerposts

Copyright © 2017 Running with Ruby

Theme by Anders NorenUp ↑