Created
July 4, 2012 19:30
-
-
Save mperham/3049152 to your computer and use it in GitHub Desktop.
Thread-friendly shared connection
This file contains hidden or 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
class ActiveRecord::Base | |
mattr_accessor :shared_connection | |
@@shared_connection = nil | |
def self.connection | |
@@shared_connection || ConnectionPool::Wrapper.new(:size => 1) { retrieve_connection } | |
end | |
end | |
ActiveRecord::Base.shared_connection = ActiveRecord::Base.connection |
This file contains hidden or 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
class ActiveRecord::Base | |
mattr_accessor :shared_connection | |
@@shared_connection = nil | |
def self.connection | |
@@shared_connection || retrieve_connection | |
end | |
end | |
ActiveRecord::Base.shared_connection = ActiveRecord::Base.connection |
This file contains hidden or 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
Capybara uses two threads to run client and server. If you just cargo cult | |
the DatabaseCleaner code that is floating around, you can run into | |
https://github.com/brianmario/mysql2/issues/99 because the threads will | |
occasionally use the same connection at the same time. | |
The fix is to use a single connection but protect access to it by having each | |
thread "check out" the connection when they are using it. This is trivial to | |
do with the `connection_pool` gem. Add it to your Gemfile and use the "after" | |
code above. |
@pratik60
Solves
PG::UnableToSend: another command is already in progress
and
undefined method 'fields'
and other flaky race errors.
class ActiveRecord::Base
mattr_accessor :shared_connection
@@shared_connection = nil
def self.connection
@@shared_connection || ConnectionPool::Wrapper.new(:size => 1) { retrieve_connection }
end
end
ActiveRecord::Base.shared_connection = ActiveRecord::Base.connection
# hack a mutex in the query execution so that we don't
# get competing queries that can timeout and not get cleaned up
module MutexLockedQuerying
@@semaphore = Mutex.new
def async_exec(*)
@@semaphore.synchronize { super }
end
end
PG::Connection.prepend(MutexLockedQuerying)
Check out https://gist.github.com/josevalim/470808 for more history on the issue.
I would say avoiding shared state is far from cargo culting. It actually avoids a bunch of hard-to-debug problems quite nicely.
+1
Just like siva3395 commented on Dec 5, 2013, I am getting this error:
Failure/Error: class ActiveRecord::Base
NameError:
uninitialized constant ActiveRecord
./spec/spec_helper.rb:23:in `<top (required)>'
I do have the gem connection_pool installed. Any ideas on how to solve this?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@mperham -: Hey, we used the earlier code which resulted in the following.
PG::UnableToSend: another command is already in progress
Then we found your code, but initially it couldn't find a few fields within the thread, but after running a few times our thread seems stuck now as a result. Its so flaky and hard to get what's happening.
Any one has any idea, what I can do to fix it? Faced similar issues?