[Zope] Re: zope fork in external method - mysql connection dropped
Chris McDonough
chrism at plope.com
Mon Oct 16 18:04:45 EDT 2006
You might also try running zope under runzope instead of under
zopectl. IIRC zopectl itself sets signal handlers and performs a
fork before starting zope, so the inherited environment may not be
what you think it is.
- C
On Oct 16, 2006, at 4:31 PM, 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)
>> Good luck!
>> Jonathan
>>
> _______________________________________________
> Zope maillist - Zope at zope.org
> http://mail.zope.org/mailman/listinfo/zope
> ** No cross posts or HTML encoding! **
> (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce
> http://mail.zope.org/mailman/listinfo/zope-dev )
>
More information about the Zope
mailing list