I am also having problems with the connection pool trying to run the Sinatra / ActiveRecord application in multithreaded mode in the Glassfishv3 container. The application includes a "before" block with ActiveRecord::Base.connection to force a connection belonging to the stream, and a "after" block with ActiveRecord::Base.clear_active_connections! to free this connection.
Multithreaded mode
I tried many variations of ActiveRecord 3.0.12 and 3.2.3, JNDI with the Glassfish connection pool, just using the ActiveRecord connection pool or even a monkey setting up the ActiveRecord connection pool to completely bypass it using the Glassfish pool directly.
When testing with a simple multi-threaded HTTP receiver, all the deviations I tried led to errors with a large percentage of failed requests, as I increase workflows in the HTTP collector.
With AR 3.0.12, a typical error is the Glassfish pool, which throws a timeout exception (for what it costs, my AR connection pool is larger than my Glassfish pool, I understand that AR will merge the connection adapter object, and arjdbc will acquire and release the actual connections backstage).
With AR 3.2.3, I get a more ominous error. The error resulted from a test that does not use JNDI, but simply using the ActiveRecord connection pool. This is one of the best configurations in that about 95% of requests are completed OK. Errors fail with this exception:
org.jruby.exceptions.RaiseException: (ConcurrencyError) Detected invalid hash contents due to unsynchronized modifications with concurrent users at org.jruby.RubyHash.keys(org/jruby/RubyHash.java:1356) at ActiveRecord::ConnectionAdapters::ConnectionPool.release(/Users/pat/app/glassfish/glassfish3/glassfish/domains/domain1/applications/lookup_service/WEB-INF/gems/gems/activerecord-3.2.3/lib/active_record/connection_adapters/abstract/connection_pool.rb:294) at ActiveRecord::ConnectionAdapters::ConnectionPool.checkin(/Users/pat/app/glassfish/glassfish3/glassfish/domains/domain1/applications/lookup_service/WEB-INF/gems/gems/activerecord-3.2.3/lib/active_record/connection_adapters/abstract/connection_pool.rb:282) at MonitorMixin.mon_synchronize(classpath:/META-INF/jruby.home/lib/ruby/1.9/monitor.rb:201) at MonitorMixin.mon_synchronize(classpath:/META-INF/jruby.home/lib/ruby/1.9/monitor.rb:200) at ActiveRecord::ConnectionAdapters::ConnectionPool.checkin(/Users/pat/app/glassfish/glassfish3/glassfish/domains/domain1/applications/lookup_service/WEB-INF/gems/gems/activerecord-3.2.3/lib/active_record/connection_adapters/abstract/connection_pool.rb:276) at ActiveRecord::ConnectionAdapters::ConnectionPool.release_connection(/Users/pat/apps/glassfish/glassfish3/glassfish/domains/domain1/applications/lookup_service/WEB-INF/gems/gems/activerecord-3.2.3/lib/active_record/connection_adapters/abstrac/connection_pool.rb:110) at ActiveRecord::ConnectionAdapters::ConnectionHandler.clear_active_connections!(/Users/pat/apps/glassfish/glassfish3/glassfish/domains/domain1/applications/lookup_service/WEB-INF/gems/gems/activerecord-3.2.3/lib/active_record/connection_adapters/abstract/connection_pool.rb:375) ...
Single-threaded mode
Losing confidence in the overall security of ActiveRecord (or arjdbc?) Threads, I refused to use the multi-threaded and configured warbler ActiveRecord and JRuby-Rack do JRuby , emulating several single-threaded Ruby processes like Unicorn, Thin, and other typical Ruby servers.
In config / warble.rb:
config.webxml.jruby.min.runtimes = 10 config.webxml.jruby.max.runtimes = 10
I repeated my test using JNDI this time, and all requests completed without errors!
The My Glassfish connection pool is size 5. Note that jruby's runtime is longer than the connection pool size. There is probably little point in creating a JRuby runtime pool more than a database connection pool, since in this application every request consumes a database connection, but I just wanted to make sure that even taking into account the database connections, I did not get the time, which I saw in multithreaded mode.
These concurrency problems are disappointing, to say the least. Does anyone successfully use ActiveRecord with moderate concurrency? I know that in a Rails application you need to call config.threadsafe! to avoid global blocking. If you look at the code, it will not change the ActiveRecord settings; is there some kind of ActiveRecord configuration that I am not doing?