Specifically regarding a Thread outside of the main request thread holding onto a connection, you might be interested in https://github.com/rails/rails/pull/14360 about more intelligently reaping connections held onto by dead threads.
Unfortunately, the comments on that PR say it will not be backported to 4.1 and will only be included in 4.2 :( On Fri, May 30, 2014 at 9:10 AM, Rodrigo Rosenfeld Rosas <[email protected] > wrote: > Yesterday someone commented in my article on Sequel, where I compare it > with AR in some aspects, including pool management: > > > http://rosenfeld.herokuapp.com/en/articles/ruby-rails/2013-12-18-sequel-is-awesome-and-much-better-than-activerecord > > To answer his comments I decided to first take a glance at the current > (4.1.1) implementation of how the connections' pool work in Rails with AR. > > After our discussion in the comments, when I was about to sleep, I was > thinking more about this subject and decided it might worth bringing some > ideas to you, in case you'd be interested on them... > > Basically, ActiveRecord currently relies on delegating the connection pool > management to the user. Most users don't realize it because they don't > usually spawn new threads from the main request thread and there's an AR > middleware that's automatically integrated to Rails that will checkin the > connection back to the pool in the end of the request. Since the connection > id is set in a thread local that means the Rack middleware can only checkin > the connection used in the main request thread. Here's some example to > illustrate: > > class MainController def index Thread.start{ Post.count } head :ok > endend > > > Assuming the default pool size (5), running this action 6 times will fail > currently: > > ab -n 6 -c 1 http://localhost:3000/main/index > > This is not anything new and Aaron Patterson has already touched this > subject long ago, in 2011: > > > http://tenderlovemaking.com/2011/10/20/connection-management-in-activerecord.html > > In a side note, yesterday I learned about an interesting project to set a > common API for job libraries that is intended to be merged to Rails at some > point: > > https://github.com/rails/activejob > > The default adapter (inline) implements an "enqueue_at" method that will > spawn a new thread: > > > https://github.com/rails/activejob/blob/master/lib/active_job/queue_adapters/inline_adapter.rb#L9-L18 > > So, calling enqueue_at for a job using the default adapter will share the > same problems of the implementation above. > > Then I was thinking that most of AR API could be implemented in a smarter > way, so that this wouldn't be a problem. That means calling > "with_connection" behind the scenes whenever they need a connection. > > Also, even "execute" could be implemented this way. Instead of checking > out a connection by calling AR::Base.connection, it could simply return a > proxy. If you really want to checkout and reserve that connection you could > call "connection.lock" for instance and then the user would know that they > must ensure "unlock" is called after it's done. But otherwise, calling > "execute" would perform the query under a "with_connection" block, checking > the connection in back to the pool after running the SQL statement. > > I'm just suggesting the idea in case someone might be interested in coming > up with a PoC for this in case the core team agrees with the suggested > approach (it introduces a bit of backward incompatibilities). I don't plan > to work on this, specially because I don't use AR myself, but maybe a > better automatic handling of connections in the pool might be of interest > to most AR users... > > Cheers, > Rodrigo. > > -- > You received this message because you are subscribed to the Google Groups > "Ruby on Rails: Core" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > To post to this group, send email to [email protected]. > Visit this group at http://groups.google.com/group/rubyonrails-core. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/rubyonrails-core. For more options, visit https://groups.google.com/d/optout.
