From: Daniel DeLorme Date: 2009-05-21T09:38:10+09:00 Subject: Re: mysql vs. fork Robert Klemme wrote: >> 1 db1 = mysql_connect() >> 2 Process.fork do >> 3 at_exit{exit!} > > That line above looks dangerous. After all, what's the point in forcing > an exit while we are exiting? > >> 4 db2 = mysql_connect() >> 5 db2.query(...) >> 6 end >> 7 Process.wait >> 8 db1.query(...) >> >> With line 3, only the at_exit handlers defined in the child process are >> run when the child exits, ensuring that db1 stays alive and line 8 keeps >> working. > > Not sure whether that's true. May well be that exit! interrupts the > exit handler process... Yes, that's exactly what it does. And since at_exit handlers are run from last defined to first defined, line 3 causes any handlers defined in the parent process to be skipped. Far from dangerous, it's safer to have the at_exit handlers run only once, in the parent. > The problem with your approach is that your client inherits the DB > connection. That's bad because the server thinks he has one peer only. > It's not much of an issue if the child does not use the socket but it > would be better to close it. Unfortunately you cannot simply close it > because you likely won't get access to it as it is buried somewhere in > your DB connection class. And if you use the connection's close method > chances are that the server shuts down the socket and both clients suffer. Thanks, that clears up some confusion I had. So closing a forked socket in a child is not a problem at all; the only problem is if the child somehow signals to the mysql server that it's ok the close the socket. With the at_exit handler that *shouldn't* happen, but obviously it's happening somehow. Now gotta find out why. > There is a much simpler solution - just don't inherit the open connection: > > 2 Process.fork do > 4 db2 = mysql_connect() > 5 db2.query(...) > 6 end > > 1 db1 = mysql_connect() > 7 Process.wait > 8 db1.query(...) Well, in my actual code the 'db1' mysql connection is opened during the program's initialization stage, way before the fork ever happens. Actually that's how I tested that the problem was really due to the fork; having the parent process reconnect to mysql after the fork (as above) stopped the errors. But reconnecting to the db whenever I want to fork seems like such a kludge. I mean, there's a number of workarounds for this problem but what I'm seeking is the reason why it's happening in the first place. -Daniel