Skip to content

Instantly share code, notes, and snippets.

@jonleighton
Created June 20, 2014 16:51
Show Gist options
  • Save jonleighton/e14088f8c8ffea3eb7c8 to your computer and use it in GitHub Desktop.
Save jonleighton/e14088f8c8ffea3eb7c8 to your computer and use it in GitHub Desktop.
# This hack is designed to prevent a thread from implicitly checking out an AR connection by
# just accessing ActiveRecord::Base.connection. The point of doing this is to ensure that threads
# don't tie up connections that they are not using, by making sure we're explicit about where we
# need to use an AR connection.
#
# See also http://tenderlovemaking.com/2011/10/20/connection-management-in-activerecord.html
ActiveSupport.on_load(:active_record) do
ActiveRecord::ConnectionAdapters::ConnectionPool # ensure loaded
if ActiveRecord::VERSION::STRING !~ /^4.0/
raise "This hack was written for Active Record 4.0. It needs to be checked " \
"in order to use it with #{ActiveRecord::VERSION::STRING}."
end
module ActiveRecord
class ImplicitConnectionDisabled < ConnectionNotEstablished
end
module DisableImplicitConnection
def connection
if conn = @reserved_connections[current_connection_id]
conn
else
if Thread.current[:allow_implicit_connection]
reserve_connection
else
raise ImplicitConnectionDisabled
end
end
end
def reserve_connection
synchronize do
@reserved_connections[current_connection_id] ||= checkout
end
end
def allow_implicit_connection
Thread.current[:allow_implicit_connection]
end
def allow_implicit_connection=(val)
Thread.current[:allow_implicit_connection] = val
end
def with_connection
prev, self.allow_implicit_connection = self.allow_implicit_connection, true
super { |c| yield c }
ensure
self.allow_implicit_connection = prev
end
end
module ReserveRackConnection
def call(env)
ActiveRecord::Base.connection_pool.allow_implicit_connection = true
super
end
end
module ConnectionAdapters
class ConnectionPool
prepend DisableImplicitConnection
end
class ConnectionManagement
prepend ReserveRackConnection
end
end
end
Thread.main[:allow_implicit_connection] = true
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment