Skip to content

Instantly share code, notes, and snippets.

@MarceloCajueiro
Created February 21, 2016 12:55
Show Gist options
  • Save MarceloCajueiro/14a8119741634ca4c029 to your computer and use it in GitHub Desktop.
Save MarceloCajueiro/14a8119741634ca4c029 to your computer and use it in GitHub Desktop.
Use database follower with Sidekiq
require 'delegate'
module SidekiqExt
# Use read-only database if :db option is :read_only,
# otherwise use the default connection.
#
# Example:
#
# class MyWorker
# include Sidekiq::Worker
#
# sidekiq_options db: :read_only
#
# def perform
# ...
# end
# end
class ReadOnlyMiddleware
# Creates a connection pool for read-only database
class ReadOnlyConnectionPoolOwner < ActiveRecord::Base
self.abstract_class = true
establish_connection("follower_#{Rails.env}")
end
class ReadOnlySwitcherConnectionHandler < SimpleDelegator
def initialize(connection_handler)
super
# Proxy the `retrieve_connection_pool` calls and return
# the properly pool connection
# IMPORTANT: This must be done here since SimpleDelegator doesn't
# wrap internal calls.
def connection_handler.retrieve_connection_pool(klass)
if Thread.current.thread_variable_get(:use_read_only_connection_pool)
super(ReadOnlyConnectionPoolOwner)
else
super
end
end
end
end
def initialize(*args)
connection_handler = ActiveRecord::Base.connection_handler
unless connection_handler.instance_of?(ReadOnlySwitcherConnectionHandler)
ActiveRecord::Base.connection_handler =
ReadOnlySwitcherConnectionHandler.new(connection_handler)
end
end
def call(worker, job, queue, &block)
db_option = (job['db'] || :master).to_sym
if db_option == :read_only
execute_using_read_only_connection(&block)
else
yield
end
end
private
def execute_using_read_only_connection(&block)
begin
Thread.current.thread_variable_set(:use_read_only_connection_pool, true)
yield
ensure
Thread.current.thread_variable_set(:use_read_only_connection_pool, false)
end
end
end
end
@MarceloCajueiro
Copy link
Author

Kudos to @tlewin.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment