From: Michal Suchanek Date: 2008-09-09T21:03:51+09:00 Subject: Re: Frustrated: System call timeouts On 09/09/2008, Mikel Lindsaar wrote: > On Sun, Sep 7, 2008 at 12:42 AM, ara.t.howard wrote: > > On Sep 6, 2008, at 3:43 AM, Mikel Lindsaar wrote: > >> Hello all, > >> I am having some (un)fun with timing out a database calls. > > > try this: > > > > > pid = Process.pid > > signaler = IO.popen "ruby -e'sleep #{ seconds }; > > Process.kill(:TERM.to_s, #{ pid }) rescue nil'" > > thread = Thread.current > > handler = Signal.trap('TERM'){ thread.raise Error, seconds.to_s } > > begin > > block.call > > ensure > > Process.kill 'TERM', signaler.pid rescue nil > > Signal.trap('TERM', handler) > > end > > > Ara, thank you _so_ much for this. > > I would never have thought of spawning suicidal terminator ruby > processes to nuke my process :) But works well. > > There was a bit of delay (putting out some fires here over the past > two days) but I got to your code last night and this morning, and it > basically works... except it doesn't kill off the signaler threads > fully. > > This is because two processes get made, first is the shell which then > creates the ruby -e "sleep..." blah thread. > > The 'hack' I used to solve this is to replace the ensure block with: > > > ensure > Process.kill 'TERM', signaler.pid rescue nil > > Process.kill('TERM', signaler.pid+1) rescue nil > > Signal.trap('TERM', handler) > end > > > But this obviously is insane as it assumes that no other processes get > started on the computer between sh starting up and it firing off the > ruby process. > > the ps output looks like this: > > $ ps -ef | grep ruby > rails 2153 2152 69 17:04 /usr/sbin/ruby1.8 /usr/bin/rake update:all > rails 2237 2153 69 17:04 sh -c ruby -e'sleep 40.0;? > Process.kill(:TERM.to_s, 2153) rescue nil' > rails 2238 2237 69 17:04 ruby -e'sleep 40.0;? > Process.kill(:TERM.to_s, 2153) rescue nil' > > Any ideas on how to reliably find the PID of the ruby process that the > sh process created by IO.popen creates? > Since you are using popen anyway you can just have your ruby process print it's PID when it starts, and read it in your terminator. HTH Michal