module ActiveRecordShards::DefaultSlavePatches

Constants

CLASS_FORCE_REPLICA_METHODS
CLASS_FORCE_SLAVE_METHODS
CLASS_REPLICA_METHODS
CLASS_SLAVE_METHODS

Public Class Methods

extended(base) click to toggle source
# File lib/active_record_shards/default_replica_patches.rb, line 90
def self.extended(base)
  CLASS_REPLICA_METHODS.each { |m| ActiveRecordShards::DefaultReplicaPatches.wrap_method_in_on_replica(true, base, m) }
  CLASS_FORCE_REPLICA_METHODS.each { |m| ActiveRecordShards::DefaultReplicaPatches.wrap_method_in_on_replica(true, base, m, force_on_replica: true) }

  if ActiveRecord::VERSION::MAJOR >= 5
    ActiveRecordShards::DefaultReplicaPatches.wrap_method_in_on_replica(true, base, :load_schema!, force_on_replica: true)
  else
    ActiveRecordShards::DefaultReplicaPatches.wrap_method_in_on_replica(true, base, :columns, force_on_replica: true)
  end

  ActiveRecordShards::DefaultReplicaPatches.wrap_method_in_on_replica(false, base, :reload)

  base.class_eval do
    include InstanceMethods

    class << self
      alias_method :transaction_without_replica_off, :transaction
      alias_method :transaction, :transaction_with_replica_off
    end
  end
end
wrap_method_in_on_replica(class_method, base, method, force_on_replica: false) click to toggle source
# File lib/active_record_shards/default_replica_patches.rb, line 5
    def self.wrap_method_in_on_replica(class_method, base, method, force_on_replica: false)
      base_methods =
        if class_method
          base.methods + base.private_methods
        else
          base.instance_methods + base.private_instance_methods
        end

      return unless base_methods.include?(method)

      _, method, punctuation = method.to_s.match(/^(.*?)([\?\!]?)$/).to_a
      # _ALWAYS_ on replica, or only for on `on_replica_by_default = true` models?
      wrapper = force_on_replica ? 'force_on_replica' : 'on_replica_unless_tx'
      base.class_eval <<-RUBY, __FILE__, __LINE__ + 1
        #{class_method ? 'class << self' : ''}
          def #{method}_with_default_replica#{punctuation}(*args, &block)
            #{wrapper} do
              #{method}_without_default_replica#{punctuation}(*args, &block)
            end
          end

          alias_method :#{method}_without_default_replica#{punctuation}, :#{method}#{punctuation}
          alias_method :#{method}#{punctuation}, :#{method}_with_default_replica#{punctuation}
        #{class_method ? 'end' : ''}
      RUBY
    end
wrap_method_in_on_slave(*args) click to toggle source
# File lib/active_record_shards/default_replica_patches.rb, line 32
def self.wrap_method_in_on_slave(*args)
  ActiveRecordShards::Deprecation.deprecation_warning(
    :'self.wrap_method_in_on_slave',
    :'self.wrap_method_in_on_replica'
  )
  wrap_method_in_on_replica(*args)
end

Public Instance Methods

force_on_replica() { || ... } click to toggle source
# File lib/active_record_shards/default_replica_patches.rb, line 124
def force_on_replica(&block)
  return yield if Thread.current[:_active_record_shards_in_migration]

  on_cx_switch_block(:replica, construct_ro_scope: false, force: true, &block)
end
on_replica_unless_tx() { || ... } click to toggle source
# File lib/active_record_shards/default_replica_patches.rb, line 112
def on_replica_unless_tx(&block)
  return yield if Thread.current[:_active_record_shards_in_migration]
  return yield if Thread.current[:_active_record_shards_in_tx]

  if on_replica_by_default?
    on_replica(&block)
  else
    yield
  end
end
Also aliased as: on_slave_unless_tx
on_slave_unless_tx(&block)
transaction_with_replica_off(*args, &block) click to toggle source
# File lib/active_record_shards/default_replica_patches.rb, line 40
def transaction_with_replica_off(*args, &block)
  if on_replica_by_default?
    begin
      old_val = Thread.current[:_active_record_shards_in_tx]
      Thread.current[:_active_record_shards_in_tx] = true
      transaction_without_replica_off(*args, &block)
    ensure
      Thread.current[:_active_record_shards_in_tx] = old_val
    end
  else
    transaction_without_replica_off(*args, &block)
  end
end
Also aliased as: transaction_with_slave_off
transaction_with_slave_off(*args, &block)