JewelRuby

... bytes and babes of JRuby

JNDI in Rails - Alice in Wonderland

AR-JDBC fix mentioned in this post is available since the 1.3.17 release.

AR-JDBC has provided support for using JNDI with ActiveRecord since the Rails “zenith” (2.x) days. Internally JNDI relies on pool checkin/checkout callbacks being triggered on adapter instances to minimize connection occupancy.

Of course, as ActiveRecord’s ConnectionPool is baked in and thus hard (although not impossible) to avoid. One needs to account for possibly double configuring pooling properties such as the size. But that’s another story.

Recently, due changes in ActiveRecord 4.2, a bug report came in that revealed an interesting issue with a jndi: configuration. Turns out for adapters that execute queries during initialize (e.g. PostgreSQL and MySQL) the JDBC connection ends up in an inconsistent state when an initializer performs any database access.

The fix is fairly simple once the moving parts are understood. To make sure the callbacks are consistently triggered, while inside the initialize method, they needed to be moved outside.

Still, not quite the happy end. With an initializer talking to the database a single JNDI connection is left open after boot (there might be more if threads are being started). Alice will stay wondering forever or at least until an abandoned connection timeout is reached.

Meet ActionDispatch::Reloader doing ActiveRecord::Base.clear_cache!. The theme around connection related caching in ActiveRecord seems that a connection is mandatory. If the current thread is not connected clear_cache! will connect (and there’s no one left to clear-up).

Rails has been rolling this way for some time (at least all 4.x versions), and while ~master~ (>= 5.0) accepted a patch there’s no word whether this small change will get back-ported to 4.2.

Sounds right to stress out standalone ActiveRecord uses are not affected, as long as they do not rely on ActiveRecord::Railtie.