ActiveRecord.connection_pool separate connections for each p

V

Virendra Negi

Hi!

I am creating an ActiveRecord connection. In my code I am forking
multiple processes which uses this ActiveRecord connection.
However when the forked process ends it release the ActiveRecord
Connection and I get the exception Mysql::Error: MySQL server has gone
away

I can catch the exception and establish the ActiveRecord connection
again, but this would involve a number or rescue statements and it would
be cumbersome.

Is it possible that I can use a connection from the connection pool and
then, each forked process uses the separate connection within the
process and return it back to the pool once i am through with it?

Thanks
Glen

Code : - fold - unfold

1. require "rubygems"
2. require "active_record"
3.
4. ActiveRecord::Base.establish_connection(
5. :adapter => "mysql",
6. :username => "root",
7. :database => "test_dev",
8. :pool => 5 # Setting the pool size to 5
9. )
10.
11. class TestDb < ActiveRecord::Base
12. set_table_name "test_dbs"
13. end
14.
15.
16. puts "Parent Process - the first record of the db is
#{TestDb.first.id}"
17.
18. Process.fork do
19. puts "In the forked process the first record id is
#{TestDb.first.id}"
20. # The forked process releases the connection here.
21. end
22.
23. sleep(2) # This is just to simulate exit of the process first and
releasing the connection.
24.
25. # No ActiveRecord connection as it has been released by the forked
process.
26. puts "Parent Process the first record id is #{Testdb.first.id}"

thank anyway
 
B

Brian Candler

I don't believe this will work as it stands. If you create a pool of 5
connections and then fork, each child process will have a copy of the
same pool. When one process 'takes' the first connection, the other
children won't be updated, so every other process will also 'take' the
same connection out of the pool. As a result, they'll all end up sharing
the same mysql connection socket, which is very dangerous here (e.g.
commands from the two processes could be intermingled, and responses
could be delivered to the wrong client)

As for when a child exits: this has been reported here before. It seems
that the mysql client sends a 'close' message down the socket in its
finalizer; that is, when the connection object is destroyed. So if two
processes really are sharing the same socket, when one terminates, the
server will be told to disconnect, so the other process will see a
disconnection too.

So you need to either:

1. Rewrite your code to use Ruby threads, instead of forking. The
connection pool will be fine then.

2. Fork first, *then* connect to the database. Then each process will
have its own separate connection.

If you are worried about the overhead of reconnecting frequently, then
start N worker processes, each of which opens a connection, and then
loops around picking jobs from a Queue.

HTH,

Brian.
 
D

Daniel DeLorme

Virendra said:
Hi!

I am creating an ActiveRecord connection. In my code I am forking
multiple processes which uses this ActiveRecord connection.
However when the forked process ends it release the ActiveRecord
Connection and I get the exception Mysql::Error: MySQL server has gone
away

I also wrestled with this problem for a long time. The problem is that
when the mysql connection is finalized, either because the process exits
or due to garbage collection, it sends a "close" message to the server.
The parent process, which uses the same connection, suddenly finds the
server is no longer there. Here is the solution that I found:

Process.fork{
ActiveRecord::Base.active_connections.values.each(&:connect)
#do your stuff here
}

This code establishes a new connection for each forked child, but
without shutting down the connection inherited from the parent.

Daniel
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,226
Members
46,815
Latest member
treekmostly22

Latest Threads

Top