Class: Rails::Sharding::ConnectionHandler
- Inherits:
-
Object
- Object
- Rails::Sharding::ConnectionHandler
- Defined in:
- lib/rails/sharding/connection_handler.rb
Class Method Summary collapse
- .connected?(shard_group, shard_name) ⇒ Boolean
- .connection_pool(shard_group, shard_name) ⇒ Object
-
.establish_all_connections ⇒ Object
Establishes connections to all shards in all shard groups.
-
.establish_connection(shard_group, shard_name, environment = nil) ⇒ Object
Establishes a connection to a single shard in a single shard group.
- .remove_connection(shard_group, shard_name) ⇒ Object
- .retrieve_connection(shard_group, shard_name) ⇒ Object
- .with_connection(shard_group, shard_name, &block) ⇒ Object
Class Method Details
.connected?(shard_group, shard_name) ⇒ Boolean
76 77 78 |
# File 'lib/rails/sharding/connection_handler.rb', line 76 def self.connected?(shard_group, shard_name) connection_handler.connected?(connection_name(shard_group, shard_name)) end |
.connection_pool(shard_group, shard_name) ⇒ Object
55 56 57 58 59 60 61 62 63 |
# File 'lib/rails/sharding/connection_handler.rb', line 55 def self.connection_pool(shard_group, shard_name) if connection_pool = connection_handler.retrieve_connection_pool(connection_name(shard_group, shard_name)) return connection_pool end # mimicking behavior of rails at: # https://github.com/rails/rails/blob/v5.0.0.1/activerecord/lib/active_record/connection_handling.rb#124 raise ActiveRecord::ConnectionNotEstablished, "No connection pool for shard #{connection_name(shard_group, shard_name)}" if connection_pool.nil? end |
.establish_all_connections ⇒ Object
Establishes connections to all shards in all shard groups. Despite the name, this actually only creates a connection pool with zero connections for each shard. The connections will be allocated for each thread when #retrieve_connection or #with_connection are called
8 9 10 11 12 13 14 |
# File 'lib/rails/sharding/connection_handler.rb', line 8 def self.establish_all_connections Core.shard_groups.each do |shard_group| Core.shard_names(shard_group).each do |shard_name| establish_connection(shard_group, shard_name) end end end |
.establish_connection(shard_group, shard_name, environment = nil) ⇒ Object
Establishes a connection to a single shard in a single shard group
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/rails/sharding/connection_handler.rb', line 17 def self.establish_connection(shard_group, shard_name, environment=nil) self.setup unless defined? @@connection_handler configurations = (environment.nil? ? Core.configurations : Core.configurations(environment)) shard_group_configurations = configurations[shard_group.to_s] if shard_group_configurations.nil? raise Errors::ConfigNotFoundError, "Cannot find configuration for shard_group '#{shard_group}' in environment '#{environment}' in #{Config.shards_config_file}" end resolver = ActiveRecord::ConnectionAdapters::ConnectionSpecification::Resolver.new(shard_group_configurations) begin connection_spec = resolver.spec(shard_name.to_sym) # since Rails 5.1 connection_spec already comes with :name set to whatever # key you used to retrieve it from the resolver, in this case the shard_name. # We don't want that, so we overwrite it with our connection name formed # by shard_group:shard_name connection_name = connection_name(shard_group, shard_name) connection_spec.instance_variable_set(:@name, connection_name) rescue ActiveRecord::AdapterNotSpecified raise Errors::ConfigNotFoundError, "Cannot find configuration for shard '#{shard_group}:#{shard_name}' in environment '#{environment}' in #{Config.shards_config_file}, or it does not specify :adapter" end # Since Rails 5.1 we cannot use connection_handler.establish_connection anymore, # because it does more than establishing_connection. It does a second # connection specification lookup on Base.configurations (where our spec # is not, because we define it in a shards.yml instead of the regular # database.yml) and it notifies subscribers of a event that does not concern # us. Because of this we directly create the connection_pool and inject to # the handler. # Note: we should consider writting our connection handler from scratch, since # it has become simpler than reusing the one from rails. And it will not break # as long as the ConnectionPool interface is stable. connection_handler.remove_connection(connection_spec.name) connection_handler.send(:owner_to_pool)[connection_spec.name] = ActiveRecord::ConnectionAdapters::ConnectionPool.new(connection_spec) end |
.remove_connection(shard_group, shard_name) ⇒ Object
90 91 92 |
# File 'lib/rails/sharding/connection_handler.rb', line 90 def self.remove_connection(shard_group, shard_name) connection_handler.remove_connection(connection_name(shard_group, shard_name)) end |
.retrieve_connection(shard_group, shard_name) ⇒ Object
65 66 67 68 69 70 71 72 73 74 |
# File 'lib/rails/sharding/connection_handler.rb', line 65 def self.retrieve_connection(shard_group, shard_name) connection_name = connection_name(shard_group, shard_name) connection = connection_handler.retrieve_connection(connection_name) if connection && Config.add_shard_tag_to_query_logs add_shard_tag_to_connection_log(connection, connection_name) else connection end end |
.with_connection(shard_group, shard_name, &block) ⇒ Object
80 81 82 83 84 85 86 87 88 |
# File 'lib/rails/sharding/connection_handler.rb', line 80 def self.with_connection(shard_group, shard_name, &block) connection_pool(shard_group, shard_name).with_connection do |connection| if connection && Config.add_shard_tag_to_query_logs connection_name = connection_name(shard_group, shard_name) add_shard_tag_to_connection_log(connection, connection_name) end block.call(connection) end end |