On Sun, Aug 19, 2007 at 06:03:34AM +0900, ara.t.howard wrote:
> 
> On Aug 18, 2007, at 12:54 PM, Jos Backus wrote:
[snip]
> does mongrel fork to accomplish that?  if not why not simply
> 
>   threads << Thread.new{ Mongrel::Runner.new.run(args) }

AfaIk, Mongrel doesn't fork so this won't work. (Hey, that rhymes!)

>> 
>> So my guess that I am using Slave wrong appears correct. The above 
>> explains
>> why the sockets remain. Since Slave.object returns a thread I figured I 
>> could
>> just join them to block the parent.
>> 
> 
> you could *if* mongrel returned an object.  the fact that i never returns 
> leaves slave half baked...

Yeah, I see that now. Otoh, if it returned it would mean that it would have
stopped running, which is, uh, undesirable. ;-)

>> Slave seemed like an easy way to manage the children and avoid zombies. Is
>> there a correct way of doing this with Slave? Or is it the wrong tool for 
>> the
>> job? In that case I'll use fork/exec, Process.waitall and a SIGTERM 
>> handler in
>> the parent which kills the children, etc. to get the job done.
>> 
> 
> i think the LifeLine class of slave is exactly what you need and that you 
> can re-use it.  basically the idea is this
> 
> socket = Socket.pair
> 
> 
> cid = fork
> 
> if cid
>   stuff
> else
>   Thread.new{ socket.read rescue exit }
>   stuff
> end
> 
> in summary, the child reads from a pipe to the parent.  if the read ever 
> returns the parent has died - so exit.  this is the 'zombie' preventer of 
> slave.rb.  if you look at slave.rb and grep for LifeLine and @lifeline 
> you'll see the usage.  summary is:
> 
> lifeline = LifeLine.new
> 
> cid = fork
> 
> unless cid # child
>   @lifeline.catch
>   @lifeline.cling
> else
>   @lifeline.throw
> end
 
I tried this and couldn't get it to work. For some reason the Mongrel children
don't progress to connect to the swiftiply proxy. Not sure why.

> and the poor man's version:
> 
> 
> 
> cfp:~ > cat a.rb
> r, w = IO.pipe
> cid = fork
> 
> unless cid ### child
>   w.close
> 
>   Thread.new{
>     begin
>       r.read
>     ensure
>       STDERR.puts 'parent died... exiting!'
>       Kernel.exit
>     end
>   }
> 
>   sleep and 'pretend some processing is going on...'
> else
>   r.close
>   sleep 2 and 'pretend the parent exited'
> end
> 
> 
> 
> cfp:~ > ruby a.rb
> parent died... exiting!
 
The poor man's version appears to work great. Thanks! I'll post a new patch to
the swiftiply list.

>> There are no references to SystemExit in swiftiply-0.6.1:
>> 
>>     # pwd
>>     /usr/lib/ruby/gems/1.8/gems/swiftiply-0.6.1
>>     # grep -r SystemExit .
>>     #
>> 
> 
> right.  but there *should* be *if* blanket Exceptions are rescued.
> 
>> Thanks for your help, Ara.
> 
> always good to have testers. er, i mean users ;-)

Surely one day soon there'll be an opportunity for me to use Slave, but this
doesn't seem to be the right fit, contrary to my earlier impression.

Thanks again for the neat blocking-pipe-read-in-thread trick, Ara. I can see
myself using it frequently in the future.

Cheers,
-- 
Jos Backus
jos at catnook.com