How to bypass CachedConnectionManager error on JBoss with JRuby?

I had a problem deploying a JRuby Rails application to JBoss using JNDI to manage database connections. After the first request, I have this error:

[CachedConnectionManager] Closing a connection for you. Please close them yourself 

I think this is because JBoss uses the connection pool and expects the rails (jruby) to release the connection after each use, which is not the case because rails (ActiveRecord) has its own connection pool.

I tried to call

 ActiveRecord::Base.clear_active_connections! 

after each request, in after_filter , but this did not work.

Does anyone have any ideas?

Thanks in advance.

+4
source share
2 answers

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?

+1
source

The Rails connection pool does not open connections, even after they return to the pool, so the underlying JDBC connection does not close. Do you use JNDI connection with activerecord-jdbc adapter ( adapter: jndi or jndi: location in database.yml)?

If so, this should happen automatically and will be a mistake.

If not, you can use the code in ar-jdbc and apply the appropriate connection pool callbacks.

https://github.com/jruby/activerecord-jdbc-adapter/blob/master/lib/arjdbc/jdbc/callbacks.rb

 class ActiveRecord::ConnectionAdapters::JdbcAdapter # This should force every connection to be closed when it gets checked back # into the connection pool include ActiveRecord::ConnectionAdapters::JndiConnectionPoolCallbacks end 
0
source

Source: https://habr.com/ru/post/1392915/


All Articles