Module: Switchman::ActiveRecord::ConnectionPool
- Defined in:
- lib/switchman/active_record/connection_pool.rb
Instance Method Summary collapse
- #checkout_new_connection ⇒ Object
- #clear_idle_connections!(since_when) ⇒ Object
- #connection ⇒ Object
- #default_schema ⇒ Object
- #release_connection(with_id = Thread.current) ⇒ Object
- #remove_shard!(shard) ⇒ Object
- #shard ⇒ Object
- #shard=(value) ⇒ Object
- #switch_database(conn) ⇒ Object
Instance Method Details
#checkout_new_connection ⇒ Object
22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/switchman/active_record/connection_pool.rb', line 22 def checkout_new_connection conn = synchronize do # ideally I would just keep a thread-local spec that I could modify # without locking anything, but if spec returns not-the-object passed # to initialize this pool, things break spec.config[:shard_name] = self.shard.name super end conn.shard = self.shard conn end |
#clear_idle_connections!(since_when) ⇒ Object
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/switchman/active_record/connection_pool.rb', line 64 def clear_idle_connections!(since_when) synchronize do @connections.reject! do |conn| if conn.last_query_at < since_when && !conn.in_use? conn.disconnect! true else false end end @available.clear @connections.each do |conn| @available.add conn end end end |
#connection ⇒ Object
35 36 37 38 39 40 |
# File 'lib/switchman/active_record/connection_pool.rb', line 35 def connection conn = super raise NonExistentShardError if shard.new_record? switch_database(conn) if conn.shard != self.shard conn end |
#default_schema ⇒ Object
14 15 16 17 18 19 20 |
# File 'lib/switchman/active_record/connection_pool.rb', line 14 def default_schema raise "Not postgres!" unless self.spec.config[:adapter] == 'postgresql' connection unless @schemas # default shard will not switch databases immediately, so it won't be set yet @schemas ||= connection.current_schemas @schemas.first end |
#release_connection(with_id = Thread.current) ⇒ Object
42 43 44 45 46 47 48 |
# File 'lib/switchman/active_record/connection_pool.rb', line 42 def release_connection(with_id = Thread.current) super(with_id) if spec.config[:idle_timeout] clear_idle_connections!(Time.now - spec.config[:idle_timeout].to_i) end end |
#remove_shard!(shard) ⇒ Object
50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/switchman/active_record/connection_pool.rb', line 50 def remove_shard!(shard) synchronize do # The shard might be currently active, so we need to update our own shard if self.shard == shard self.shard = Shard.default end # Update out any connections that may be using this shard @connections.each do |conn| # This will also update the connection's shard to the default shard switch_database(conn) if conn.shard == shard end end end |
#shard ⇒ Object
6 7 8 |
# File 'lib/switchman/active_record/connection_pool.rb', line 6 def shard Thread.current[tls_key] || Shard.default end |
#shard=(value) ⇒ Object
10 11 12 |
# File 'lib/switchman/active_record/connection_pool.rb', line 10 def shard=(value) Thread.current[tls_key] = value end |
#switch_database(conn) ⇒ Object
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/switchman/active_record/connection_pool.rb', line 81 def switch_database(conn) if !@schemas && conn.adapter_name == 'PostgreSQL' && !self.shard.database_server.config[:shard_name] @schemas = conn.current_schemas end spec.config[:shard_name] = self.shard.name case conn.adapter_name when 'MySQL', 'Mysql2' conn.execute("USE #{spec.config[:database]}") when 'PostgreSQL' if conn.schema_search_path != spec.config[:schema_search_path] conn.schema_search_path = spec.config[:schema_search_path] end when 'SQLite' # This is an artifact of the adapter modifying the path to be an absolute path when it is instantiated; just let it slide else raise("Cannot switch databases on same DatabaseServer with adapter type: #{conn.adapter_name}. Limit one Shard per DatabaseServer.") end conn.shard = shard end |