[Zope] Re: zope fork in external method - mysql connection dropped

Tres Seaver tseaver at palladion.com
Mon Oct 16 17:35:08 EDT 2006


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Daniel Lopez wrote:
> 
> I made one tweak to the double-fork procedure, adding a waitpid call in
> the grandparent process (the original zope thread) before it returns out
> of the external method... the code then looked something like:
> 
> [...prefork code up to here...]
> pid1 = os.fork()
> if pid1 > 0:
>    #grandparent waits for its child before returning
>    os.waitpid(pid1, 0)
>    return RESPONSE.redirect("wait_page")
> pid2 = os.fork()
> os.setsid()
> if pid2 > 0:
>    #child quits, orphaning grandchild
>    sys.exit(0)
> [...grandchild-only code after here...]
> 
> The waitpid call seems to be preventing the zombies... this is good!
> (though if you find something bad about this approach, please do speak up)
> 
> But in the process, a new bug was created, having to do with the MySQL
> connection.  I now receive a "Lost connection to MySQL server during
> query" error in what appears to be a final db flush from the
> grandparent's publish function (ZPublisher.Publish, line 104).  The good
> news is that the grandchild continues to do it's work, but the bad news
> is that the user receives an error page instead of the redirect to the
> "wait_page".
> 
> My guess is that this has something to do with the various forked
> processes sharing the MySQL connection, and in particular, I'm guessing
> the child process that exit(0)'s is closing the connection, which is
> then unavailable when the grandparent tries to use it.
> 
> Here's the interesting part: if I put a sleep(1) line in between the
> waitpid() line and the return line, I get no error.  It would appear
> that the 1 second pause provides enough time for a new MySQL connection
> to be made after the previous one is killed (less than 1 second is not
> enough).
> 
> This is a very ugly fix, though... I can't guarantee that 1 second will
> always be enough... can anyone suggest a cleaner solution?  Perhaps I
> shouldn't kill the child with sys.exit(0)?
> 
> -Daniel
> 
> 
> 
> On Fri, 13 Oct 2006, Jonathan wrote:
> 
>> Pls keep your posts on the list  - so that others can help and so that
>> others can search for problems/solutions!
>>
>> ----- Original Message -----
>> Sent: Friday, October 13, 2006 12:13 PM
>> Subject: zope fork in external method
>>
>>
>>>
>>> Jonathan-
>>>
>>> I'm emailing you because I saw your post a few months back at:
>>>
>>> http://mail.zope.org/pipermail/zope/2006-May/166574.html
>>>
>>> I've been doing my best to find answers on existing posts, but to no
>>> avail. Perhaps you can send further pointers?
>>>
>>> On my system, a user can hit a page that initiates a long database
>>> query. If the user hits the stop button and tries to refresh, it
>>> messes things up (by interrupting the code upon return of the query),
>>> so I came up with a solution that almost works:
>>>
>>> I put all the code into an external method, which forks.  The parent
>>> returns a redirect to a "waiting" throbber page that uses Ajax to
>>> poll whether the query is done.  The child then goes on to do the
>>> hard work.
>>>
>>> This is working as desired, with a single exception: zombie child
>>> processes. Where can I learn more about forking processes in zope
>>> external methods? I've read about the double-fork method, but that
>>> hasn't resolved the problem...
>>
>> A few ideas for reaping dead child processes:
>>
>> 1) implement a SIGCHLD handler
>>
>> 2) when a spawned child process is finished its 'zope processing' have
>> it write its process id to a file (be careful when accessing files,
>> you will need locking to eliminate problems that may be caused by
>> zope's multiple threads) and then have a clean up routine which kills
>> all of the processes listed in the file (this could be an independant
>> clean-up routine which wakes up on a regular basis, or it could be
>> built into the 'spawning' process which does the clean up before it
>> spawns a child).
>>
>> 3) as the last thing it does, have the child process issue a kill -9
>> system command to kill its own process (I haven't tried this myself,
>> but it may work and it would be simple to implement)

I'd recommend using the 'subprocess' module for such stuff.


Tres.
- --
===================================================================
Tres Seaver          +1 202-558-7113          tseaver at palladion.com
Palladion Software   "Excellence by Design"    http://palladion.com
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.2 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFFM/sM+gerLs4ltQ4RArk4AJ9BjRO44YwZYPu2Mc4wo2PVEN504gCbBIw8
ja7CChvp288LUobko5cZHqY=
=izB3
-----END PGP SIGNATURE-----



More information about the Zope mailing list