Module: ActiveRecordShards::ConnectionSwitcher
- Defined in:
- lib/active_record_shards/connection_switcher.rb,
lib/active_record_shards/connection_switcher-5-1.rb,
lib/active_record_shards/connection_switcher-6-0.rb,
lib/active_record_shards/connection_switcher-6-1.rb,
lib/active_record_shards/connection_switcher-7-0.rb
Defined Under Namespace
Classes: IsolationLevelError, LegacyConnectionHandlingError, PrimaryReplicaProxy
Instance Attribute Summary collapse
-
#_active_record_shards_disallow_replica_by_thread ⇒ Object
Returns the value of attribute _active_record_shards_disallow_replica_by_thread.
-
#_active_record_shards_in_migration ⇒ Object
Returns the value of attribute _active_record_shards_in_migration.
-
#_active_record_shards_shard_selection ⇒ Object
Returns the value of attribute _active_record_shards_shard_selection.
Class Method Summary collapse
Instance Method Summary collapse
- #connection_specification_name ⇒ Object
- #current_shard_id ⇒ Object
- #current_shard_selection ⇒ Object
- #disallow_replica ⇒ Object
- #disallow_replica=(value) ⇒ Object
- #on_all_shards ⇒ Object
- #on_cx_switch_block(which, force: false, construct_ro_scope: nil, &block) ⇒ Object
- #on_first_shard(&block) ⇒ Object
- #on_primary(&block) ⇒ Object
- #on_primary_db(&block) ⇒ Object
- #on_primary_if(condition, &block) ⇒ Object
- #on_primary_or_replica(which, &block) ⇒ Object
- #on_primary_unless(condition, &block) ⇒ Object
-
#on_replica(&block) ⇒ Object
Executes queries using the replica database.
- #on_replica? ⇒ Boolean
- #on_replica_if(condition, &block) ⇒ Object
- #on_replica_unless(condition, &block) ⇒ Object
- #on_shard(shard) ⇒ Object
- #reset_primary_key_with_default_shard ⇒ Object
- #shard_names ⇒ Object
- #shards ⇒ Object
- #supports_sharding? ⇒ Boolean
Instance Attribute Details
#_active_record_shards_disallow_replica_by_thread ⇒ Object
Returns the value of attribute _active_record_shards_disallow_replica_by_thread.
10 11 12 |
# File 'lib/active_record_shards/connection_switcher.rb', line 10 def _active_record_shards_disallow_replica_by_thread @_active_record_shards_disallow_replica_by_thread end |
#_active_record_shards_in_migration ⇒ Object
Returns the value of attribute _active_record_shards_in_migration.
10 11 12 |
# File 'lib/active_record_shards/connection_switcher.rb', line 10 def _active_record_shards_in_migration @_active_record_shards_in_migration end |
#_active_record_shards_shard_selection ⇒ Object
Returns the value of attribute _active_record_shards_shard_selection.
10 11 12 |
# File 'lib/active_record_shards/connection_switcher.rb', line 10 def _active_record_shards_shard_selection @_active_record_shards_shard_selection end |
Class Method Details
.extended(base) ⇒ Object
21 22 23 24 25 26 27 28 29 30 |
# File 'lib/active_record_shards/connection_switcher.rb', line 21 def self.extended(base) base.singleton_class.send(:alias_method, :load_schema_without_default_shard!, :load_schema!) base.singleton_class.send(:alias_method, :load_schema!, :load_schema_with_default_shard!) base.singleton_class.send(:alias_method, :table_exists_without_default_shard?, :table_exists?) base.singleton_class.send(:alias_method, :table_exists?, :table_exists_with_default_shard?) base.singleton_class.send(:alias_method, :reset_primary_key_without_default_shard, :reset_primary_key) base.singleton_class.send(:alias_method, :reset_primary_key, :reset_primary_key_with_default_shard) end |
Instance Method Details
#connection_specification_name ⇒ Object
3 4 5 6 7 8 9 10 11 |
# File 'lib/active_record_shards/connection_switcher-5-1.rb', line 3 def connection_specification_name name = current_shard_selection.resolve_connection_name(sharded: is_sharded?, configurations: configurations) unless configurations[name] || name == "primary" raise ActiveRecord::AdapterNotSpecified, "No database defined by #{name} in your database config. (configurations: #{configurations.to_h.keys.inspect})" end name end |
#current_shard_id ⇒ Object
148 149 150 |
# File 'lib/active_record_shards/connection_switcher.rb', line 148 def current_shard_id current_shard_selection.shard end |
#current_shard_selection ⇒ Object
144 145 146 |
# File 'lib/active_record_shards/connection_switcher.rb', line 144 def current_shard_selection Thread.current._active_record_shards_shard_selection ||= ShardSelection.new end |
#disallow_replica ⇒ Object
132 133 134 |
# File 'lib/active_record_shards/connection_switcher.rb', line 132 def disallow_replica Thread.current._active_record_shards_disallow_replica_by_thread ||= 0 end |
#disallow_replica=(value) ⇒ Object
128 129 130 |
# File 'lib/active_record_shards/connection_switcher.rb', line 128 def disallow_replica=(value) Thread.current._active_record_shards_disallow_replica_by_thread = value end |
#on_all_shards ⇒ Object
53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/active_record_shards/connection_switcher.rb', line 53 def on_all_shards = current_shard_selection. if supports_sharding? shard_names.map do |shard| switch_connection(shard: shard) yield(shard) end else [yield] end ensure switch_connection() end |
#on_cx_switch_block(which, force: false, construct_ro_scope: nil, &block) ⇒ Object
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/active_record_shards/connection_switcher.rb', line 108 def on_cx_switch_block(which, force: false, construct_ro_scope: nil, &block) self.disallow_replica += 1 if which == :primary switch_to_replica = force || disallow_replica.zero? = current_shard_selection. switch_connection(replica: switch_to_replica) # we avoid_readonly_scope to prevent some stack overflow problems, like when # .columns calls .with_scope which calls .columns and onward, endlessly. if self == ActiveRecord::Base || !switch_to_replica || construct_ro_scope == false || ActiveRecordShards.disable_replica_readonly_records == true yield else readonly.scoping(&block) end ensure self.disallow_replica -= 1 if which == :primary switch_connection() if end |
#on_first_shard(&block) ⇒ Object
44 45 46 47 |
# File 'lib/active_record_shards/connection_switcher.rb', line 44 def on_first_shard(&block) shard_name = shard_names.first on_shard(shard_name, &block) end |
#on_primary(&block) ⇒ Object
104 105 106 |
# File 'lib/active_record_shards/connection_switcher.rb', line 104 def on_primary(&block) on_primary_or_replica(:primary, &block) end |
#on_primary_db(&block) ⇒ Object
32 33 34 |
# File 'lib/active_record_shards/connection_switcher.rb', line 32 def on_primary_db(&block) on_shard(nil, &block) end |
#on_primary_if(condition, &block) ⇒ Object
75 76 77 |
# File 'lib/active_record_shards/connection_switcher.rb', line 75 def on_primary_if(condition, &block) condition ? on_primary(&block) : yield end |
#on_primary_or_replica(which, &block) ⇒ Object
83 84 85 86 87 88 89 |
# File 'lib/active_record_shards/connection_switcher.rb', line 83 def on_primary_or_replica(which, &block) if block_given? on_cx_switch_block(which, &block) else PrimaryReplicaProxy.new(self, which) end end |
#on_primary_unless(condition, &block) ⇒ Object
79 80 81 |
# File 'lib/active_record_shards/connection_switcher.rb', line 79 def on_primary_unless(condition, &block) on_primary_if(!condition, &block) end |
#on_replica(&block) ⇒ Object
Executes queries using the replica database. Fails over to primary if no replica is found. if you want to execute a block of code on the replica you can go:
Account.on_replica do
Account.first
end
the first account will be found on the replica DB
For one-liners you can simply do
Account.on_replica.first
100 101 102 |
# File 'lib/active_record_shards/connection_switcher.rb', line 100 def on_replica(&block) on_primary_or_replica(:replica, &block) end |
#on_replica? ⇒ Boolean
140 141 142 |
# File 'lib/active_record_shards/connection_switcher.rb', line 140 def on_replica? current_shard_selection.on_replica? end |
#on_replica_if(condition, &block) ⇒ Object
67 68 69 |
# File 'lib/active_record_shards/connection_switcher.rb', line 67 def on_replica_if(condition, &block) condition ? on_replica(&block) : yield end |
#on_replica_unless(condition, &block) ⇒ Object
71 72 73 |
# File 'lib/active_record_shards/connection_switcher.rb', line 71 def on_replica_unless(condition, &block) on_replica_if(!condition, &block) end |
#on_shard(shard) ⇒ Object
36 37 38 39 40 41 42 |
# File 'lib/active_record_shards/connection_switcher.rb', line 36 def on_shard(shard) = current_shard_selection. switch_connection(shard: shard) if supports_sharding? yield ensure switch_connection() end |
#reset_primary_key_with_default_shard ⇒ Object
156 157 158 |
# File 'lib/active_record_shards/connection_switcher.rb', line 156 def reset_primary_key_with_default_shard with_default_shard { reset_primary_key_without_default_shard } end |
#shard_names ⇒ Object
152 153 154 |
# File 'lib/active_record_shards/connection_switcher.rb', line 152 def shard_names config_for_env[SHARD_NAMES_CONFIG_KEY] || [] end |
#shards ⇒ Object
49 50 51 |
# File 'lib/active_record_shards/connection_switcher.rb', line 49 def shards ShardSupport.new(self == ActiveRecord::Base ? nil : where(nil)) end |
#supports_sharding? ⇒ Boolean
136 137 138 |
# File 'lib/active_record_shards/connection_switcher.rb', line 136 def supports_sharding? shard_names.any? end |