Daniel DeLorme
5/21/2009 12:38:00 AM
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