Module: SeamlessDatabasePool
- Defined in:
- lib/seamless_database_pool.rb,
lib/seamless_database_pool/railtie.rb,
lib/seamless_database_pool/controller_filter.rb,
lib/seamless_database_pool/connection_statistics.rb
Overview
This module allows setting the read pool connection type. Generally you will use one of
- use_random_read_connection
- use_persistent_read_connection
- use_master_connection
Each of these methods can take an optional block. If they are called with a block, they will set the read connection type only within the block. Otherwise they will set the default read connection type. If none is ever called, the read connection type will be :master.
Defined Under Namespace
Modules: ConnectionStatistics, ControllerFilter, ControllerFilterHooks Classes: Railtie
Constant Summary collapse
- ADAPTER_TO_CLASS_NAME_MAP =
Adapter name to class name map. This exists because there isn’t an obvious way to translate things like sqlite3 to SQLite3. The adapters that ship with ActiveRecord are defined here. If you use an adapter that doesn’t translate directly to camel case, then add the mapping here in an initializer.
{"sqlite" => "SQLite", "sqlite3" => "SQLite3", "postgresql" => "PostgreSQL"}
- READ_CONNECTION_METHODS =
[:master, :persistent, :random]
Class Method Summary collapse
-
.adapter_class_for(name) ⇒ Object
Get the connection adapter class for an adapter name.
- .clear_read_only_connection ⇒ Object
-
.master_database_configuration(database_configs) ⇒ Object
Pull out the master configuration for compatibility with such things as the Rails’ rake db:* tasks which only support known adapters.
-
.read_only_connection(pool_connection) ⇒ Object
Get a read only connection from a connection pool.
-
.read_only_connection_type(default = :master) ⇒ Object
Get the read only connection type currently in use.
-
.set_persistent_read_connection(pool_connection, read_connection) ⇒ Object
This method is provided as a way to change the persistent connection when it fails and a new one is substituted.
-
.set_read_only_connection_type(connection_type) ⇒ Object
Set the read only connection type to either :master, :random, or :persistent.
-
.use_master_connection ⇒ Object
Call this method to use the master connection for all subsequent select statements.
-
.use_persistent_read_connection ⇒ Object
Call this method to pick a random connection from the read pool and use it for all subsequent select statements.
-
.use_random_read_connection ⇒ Object
Call this method to use a random connection from the read pool for every select statement.
Class Method Details
.adapter_class_for(name) ⇒ Object
Get the connection adapter class for an adapter name. The class will be loaded from ActiveRecord::ConnectionAdapters::NameAdapter where Name is the camelized version of the name. If the adapter class does not fit this pattern (i.e. sqlite3 => SQLite3Adapter), then add the mapping to the ADAPTER_TO_CLASS_NAME_MAP
Hash.
125 126 127 128 129 |
# File 'lib/seamless_database_pool.rb', line 125 def adapter_class_for(name) name = name.to_s class_name = ADAPTER_TO_CLASS_NAME_MAP[name] || name.camelize "ActiveRecord::ConnectionAdapters::#{class_name}Adapter".constantize end |
.clear_read_only_connection ⇒ Object
117 118 119 |
# File 'lib/seamless_database_pool.rb', line 117 def clear_read_only_connection Thread.current[:read_only_connection] = nil end |
.master_database_configuration(database_configs) ⇒ Object
Pull out the master configuration for compatibility with such things as the Rails’ rake db:* tasks which only support known adapters.
133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/seamless_database_pool.rb', line 133 def master_database_configuration(database_configs) configs = {} database_configs.each do |key, values| if values['adapter'] == 'seamless_database_pool' values['adapter'] = values.delete('pool_adapter') values = values.merge(values['master']) if values['master'].is_a?(Hash) values.delete('pool_weight') values.delete('master') values.delete('read_pool') end configs[key] = values end configs end |
.read_only_connection(pool_connection) ⇒ Object
Get a read only connection from a connection pool.
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/seamless_database_pool.rb', line 93 def read_only_connection(pool_connection) return pool_connection.master_connection if pool_connection.using_master_connection? connection_type = Thread.current[:read_only_connection] if connection_type.kind_of?(Hash) connection = connection_type[pool_connection] unless connection connection = pool_connection.random_read_connection connection_type[pool_connection] = connection end return connection elsif connection_type == :random return pool_connection.random_read_connection else return pool_connection.master_connection end end |
.read_only_connection_type(default = :master) ⇒ Object
Get the read only connection type currently in use. Will be one of :master, :random, or :persistent.
86 87 88 89 90 |
# File 'lib/seamless_database_pool.rb', line 86 def read_only_connection_type(default = :master) connection_type = Thread.current[:read_only_connection] || default connection_type = :persistent if connection_type.kind_of?(Hash) return connection_type end |
.set_persistent_read_connection(pool_connection, read_connection) ⇒ Object
This method is provided as a way to change the persistent connection when it fails and a new one is substituted.
112 113 114 115 |
# File 'lib/seamless_database_pool.rb', line 112 def set_persistent_read_connection(pool_connection, read_connection) connection_type = Thread.current[:read_only_connection] connection_type[pool_connection] = read_connection if connection_type.kind_of?(Hash) end |
.set_read_only_connection_type(connection_type) ⇒ Object
Set the read only connection type to either :master, :random, or :persistent.
72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/seamless_database_pool.rb', line 72 def set_read_only_connection_type(connection_type) saved_connection = Thread.current[:read_only_connection] retval = nil begin connection_type = {} if connection_type == :persistent Thread.current[:read_only_connection] = connection_type retval = yield if block_given? ensure Thread.current[:read_only_connection] = saved_connection end return retval end |
.use_master_connection ⇒ Object
Call this method to use the master connection for all subsequent select statements. This method is most useful when you are doing lots of updates since it guarantees consistency if you do a select immediately after an update or insert.
The master connection will also be used for selects inside any transaction blocks. It will also be used if you pass :readonly => false to any ActiveRecord.find method.
63 64 65 66 67 68 69 |
# File 'lib/seamless_database_pool.rb', line 63 def use_master_connection if block_given? set_read_only_connection_type(:master){yield} else Thread.current[:read_only_connection] = :master end end |
.use_persistent_read_connection ⇒ Object
Call this method to pick a random connection from the read pool and use it for all subsequent select statements. This provides consistency from one select statement to the next. This method should always be called with a block otherwise you can end up with an imbalanced read pool. This method is best if you have lots of processes which have a relatively few select statements or a slow replication mechanism. Generally this is the best method to use for web applications.
49 50 51 52 53 54 55 |
# File 'lib/seamless_database_pool.rb', line 49 def use_persistent_read_connection if block_given? set_read_only_connection_type(:persistent){yield} else Thread.current[:read_only_connection] = {} end end |
.use_random_read_connection ⇒ Object
Call this method to use a random connection from the read pool for every select statement. This method is good if your replication is very fast. Otherwise there is a chance you could get inconsistent results from one request to the next. This can result in mysterious failures if your code selects a value in one statement and then uses in another statement. You can wind up trying to use a value from one server that hasn’t been replicated to another one yet. This method is best if you have few processes which generate a lot of queries and you have fast replication.
35 36 37 38 39 40 41 |
# File 'lib/seamless_database_pool.rb', line 35 def use_random_read_connection if block_given? set_read_only_connection_type(:random){yield} else Thread.current[:read_only_connection] = :random end end |