Lines of Code Code Status Dependency Status Build Status Coverage Status Downloads

Bg

Non-blocking ActiveRecord method invocation

This library allows you to invoke ActiveRecord instance methods in the background.

  • Bg::Asyncable uses concurrent-ruby to execute methods in a different thread
  • Bg::Deferrable uses ActiveJob to execute methods in a background process

Quickstart

Setup

class User < ApplicationRecord
  include Bg::Asyncable  # uses concurrent-ruby
  include Bg::Deferrable # uses ActiveJob
end

Usage

user = User.find(params[:id])

# blocking in-process
user.do_hard_work

# non-blocking in-process separate thread
user.async.do_hard_work

# non-blocking out-of-process background job
user.defer.do_hard_work
user.defer(queue: :low, wait: 5.minutes).do_hard_work

Deferrable

Bg::Deferrable leverages GlobalID::Identification to marshal ActiveRecord instances across process boundaries. This means that state is not shared between the main process & the process actually executing the method.

  • Do not depend on lexically scoped bindings when invoking methods.
  • Do not pass unmarshallable types as arguments. Bg::Deferrable will prepare arguments for enqueuing, but best practice is to follow Sidekiq's simple parameters rule.

Examples

Good

user = User.find(params[:id])
user.defer.do_hard_work 1, true, "foo"

Bad

user = User.find(params[:id])
# in memory changes will not be available in Bg::Deferrable invoked methods
user.name = "new value"

# args may not marshal properly
user.defer.do_hard_work :foo, Time.now, instance_of_complex_type

user.defer.do_hard_work do
  # blocks are not supported
end

Asyncable

Bg::Asyncable disallows invoking methods that take blocks as an argument.

  • Important: It's your responsibility to protect shared data between threads

Examples

Good

user = User.find(params[:id])
user.name = "new value"
user.async.do_hard_work 1, true, "foo"
user.async.do_hard_work :foo, Time.now, instance_of_complex_type

Bad

user = User.find(params[:id])

user.async.do_hard_work do
  # blocks are not supported
end