Module: Ec::Pg::ShardManager
- Defined in:
- lib/ec/pg/shard_manager.rb
Overview
Manages ActiveRecord database shard switching.
Leverages ActiveRecord’s native multi-database support (AR 6.1+) via connected_to(shard:). Falls back to manual connection swapping for connection configurations that are not registered as named shards.
Configuration in database.yml (Rails multi-db style)
production:
primary:
<<: *default
database: app_primary
db_sharded_shard_1:
<<: *default
database: app_shard_one
migrations_paths: db/migrate_shards
Usage
ShardManager.with_shard(:shard_one) { User.all }
ShardManager.with_shard(:shard_one, role: :reading) { User.all }
Defined Under Namespace
Classes: ShardNotFound, UnsupportedActiveRecordVersion
Constant Summary collapse
- MinimumARVersion =
Gem::Version.new("7.1")
Class Method Summary collapse
-
.active? ⇒ Boolean
Returns true when the thread is operating inside a
with_shardblock (or when the shard was set via thread-local assignment). - .assert_ar_version! ⇒ Object
-
.current_shard ⇒ Object
Returns the shard currently set in thread context, or
:defaultwhen none is set (mirrors how AR treats the default shard). -
.with_shard(shard_name, role: :writing, klass: ActiveRecord::Base) { ... } ⇒ Object
Executes
blockwith the AR connection switched toshard_name.
Class Method Details
.active? ⇒ Boolean
Returns true when the thread is operating inside a with_shard block (or when the shard was set via thread-local assignment).
59 60 61 |
# File 'lib/ec/pg/shard_manager.rb', line 59 def active? !Context.shard.nil? end |
.assert_ar_version! ⇒ Object
82 83 84 85 86 87 88 89 |
# File 'lib/ec/pg/shard_manager.rb', line 82 def assert_ar_version! ar_version = Gem::Version.new(ActiveRecord.version.to_s) return if ar_version >= MinimumARVersion raise UnsupportedActiveRecordVersion, "activerecord-multi-tenant shard switching requires ActiveRecord >= 6.1. " \ "Current version: #{ar_version}" end |
.current_shard ⇒ Object
Returns the shard currently set in thread context, or :default when none is set (mirrors how AR treats the default shard).
65 66 67 |
# File 'lib/ec/pg/shard_manager.rb', line 65 def current_shard Context.shard || :default end |
.with_shard(shard_name, role: :writing, klass: ActiveRecord::Base) { ... } ⇒ Object
Executes block with the AR connection switched to shard_name.
42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/ec/pg/shard_manager.rb', line 42 def with_shard(shard_name, role: :writing, klass: ActiveRecord::Base, &block) shard_name = shard_name.to_sym assert_ar_version! Context.with(shard: shard_name) do klass.prohibit_shard_swapping(true) do klass.connected_to(shard: shard_name, role: role, &block) end end rescue ActiveRecord::ConnectionNotEstablished => e raise ShardNotFound, "Could not connect to shard #{shard_name.inspect}. " \ "Make sure it is registered via connects_to. Original error: #{e.}" end |