Class: AutoReplica::AdHocConnectionHandler

Inherits:
ConnectionHandler show all
Defined in:
lib/activerecord_autoreplica.rb

Overview

A connection handler that creates an ad-hoc read connection pool, and disconnects it when finishing

Instance Method Summary collapse

Methods inherited from ConnectionHandler

#clear_all_connections!, #disconnect_read_pool!, #method_missing, #release_read_pool_connection, #respond_to_missing?, #retrieve_connection

Constructor Details

#initialize(original_handler, replica_connection_spec_hash_or_url) ⇒ AdHocConnectionHandler

Returns a new instance of AdHocConnectionHandler.



125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/activerecord_autoreplica.rb', line 125

def initialize(original_handler, replica_connection_spec_hash_or_url)
  connection_specification_hash = parse_params(replica_connection_spec_hash_or_url)
  # We need to maintain our own pool for read replica connections,
  # aside from the one managed by Rails proper.
  adapter_method = "%s_connection" % connection_specification_hash[:adapter]
  connection_specification = begin
    ConnectionSpecification.new('autoreplica', connection_specification_hash, adapter_method)
  rescue ArgumentError # AR 4 and lower wants 2 arguments
    ConnectionSpecification.new(connection_specification_hash, adapter_method)
  end
  read_pool = ActiveRecord::ConnectionAdapters::ConnectionPool.new(connection_specification)
  super(original_handler, read_pool)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class AutoReplica::ConnectionHandler

Instance Method Details

#finishObject

Disconnect all read pool connections, making the pool ready to be disposed.



167
168
169
# File 'lib/activerecord_autoreplica.rb', line 167

def finish
  disconnect_read_pool!
end

#parse_params(replica_connection_spec_hash_or_url) ⇒ Object



139
140
141
142
143
144
145
146
147
148
# File 'lib/activerecord_autoreplica.rb', line 139

def parse_params(replica_connection_spec_hash_or_url)
  # Resolve if there is a URL given
  # Duplicate the hash so that we can change it if we have to
  # (say by deleting :adapter)
  if replica_connection_spec_hash_or_url.is_a?(Hash)
    replica_connection_spec_hash_or_url.dup
  else
    resolve_connection_url(replica_connection_spec_hash_or_url).dup
  end
end

#resolve_connection_url(url_string) ⇒ Hash

Resolve an ActiveRecord connection URL, from a string to a Hash.

Parameters:

  • url_string (String)

    the connection URL (like sqlite3://...)

Returns:

  • (Hash)

    a symbol-keyed ActiveRecord connection specification



154
155
156
157
158
159
160
161
162
163
164
# File 'lib/activerecord_autoreplica.rb', line 154

def resolve_connection_url(url_string)
  # TODO: privatize this method.
  if defined?(ActiveRecord::Base::ConnectionSpecification::Resolver) # AR3
    resolver = ActiveRecord::Base::ConnectionSpecification::Resolver.new(url_string, {})
    resolver.send(:connection_url_to_hash, url_string) # Because making this public was so hard
  else  # AR4
    resolved = ActiveRecord::ConnectionAdapters::ConnectionSpecification::ConnectionUrlResolver.new(url_string).to_hash
    resolved["database"].gsub!(/^\//, '') # which is not done by the resolver
    resolved.symbolize_keys # which is also not done by the resolver
  end
end