Created
June 20, 2014 16:51
-
-
Save jonleighton/e14088f8c8ffea3eb7c8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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