Keying these hashes by klass causes reloadable classes to never get
freed. Thanks to @thedarkone for pointing this out in
the comments on 221571beb6b4bb7437989bdefaf421f993ab6002.
This doesn't seem to make a massive difference to performance.
Benchmark
---------
require 'active_record'
require 'benchmark/ips'
class Post < ActiveRecord::Base
establish_connection adapter: 'sqlite3', database: ':memory:'
end
GC.disable
Benchmark.ips(20) do |r|
r.report { Post.connection }
end
Before
------
Calculating -------------------------------------
5632 i/100ms
-------------------------------------------------
218671.0 (±1.9%) i/s - 4364800 in 19.969401s
After
-----
Calculating -------------------------------------
8743 i/100ms
-------------------------------------------------
206525.9 (±17.8%) i/s - 4039266 in 19.992590s
In the end I think the pain of implementing this seamlessly was not
worth the gain provided.
The intention was that it would allow plain ruby objects that might not
live in your main application to be subclassed and have persistence
mixed in. But I've decided that the benefit of doing that is not worth
the amount of complexity that the implementation introduced.
The core of this fix is a threadsafe, fair Queue class. It is
very similar to Queue in stdlib except that it supports waiting
with a timeout.
The issue this solves is that if several threads are contending for
database connections, an unfair queue makes is possible that a thread
will timeout even while other threads successfully acquire and release
connections. A fair queue means the thread that has been waiting the
longest will get the next available connection.
This includes a few test fixes to avoid test ordering issues that
cropped up during development of this patch.
This reverts commit d2901f0fc4270a765717ad572d559dc49a56b3a8, reversing
changes made to 525839fdd8cc34d6d524f204528d5b6f36fe410c.
Conflicts:
activerecord/test/cases/connection_pool_test.rb
Reason: This change broke the build (http://travis-ci.org/#!/rails/rails/builds/1391490)
and we don't have any solution until now. I asked the author to try to
fix it and open a new pull request.