Module: Collective::Utilities::Process
Instance Method Summary collapse
- #alive?(pid) ⇒ Boolean
- #fork_and_detach(options = {}, &action) ⇒ Object
- #redirect_stdio(stdout) ⇒ Object
- #wait2_now(pid) ⇒ Object
- #wait_and_terminate(pid, options = {}) ⇒ Object
- #wait_until_deadline(pid, deadline) ⇒ Object
Instance Method Details
#alive?(pid) ⇒ Boolean
74 75 76 77 78 |
# File 'lib/collective/utilities/process.rb', line 74 def alive?( pid ) !! ::Process.kill( 0, pid ) rescue Errno::ESRCH false end |
#fork_and_detach(options = {}, &action) ⇒ Object
39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/collective/utilities/process.rb', line 39 def fork_and_detach( = {}, &action) # Fork twice. First child doesn't matter. The second is our favorite. pid1 = fork do ::Process.setsid exit if fork redirect_stdio( [:stdout] ) action.call end # We must call waitpid on the first child to keep it from turning into a zombie ::Process.waitpid(pid1) end |
#redirect_stdio(stdout) ⇒ Object
60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/collective/utilities/process.rb', line 60 def redirect_stdio( stdout ) STDIN.reopen "/dev/null" if stdout then mask = File.umask(0000) file = File.new( stdout, "a" ) # append or create, write only File.umask( mask ) STDOUT.reopen( file ) else STDOUT.reopen "/dev/null" end STDERR.reopen(STDOUT) end |
#wait2_now(pid) ⇒ Object
53 54 55 56 57 |
# File 'lib/collective/utilities/process.rb', line 53 def wait2_now( pid ) ::Process.wait2( pid, ::Process::WNOHANG ) rescue Errno::ECHILD # No child processes return [ nil, 0 ] end |
#wait_and_terminate(pid, options = {}) ⇒ Object
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/collective/utilities/process.rb', line 19 def wait_and_terminate( pid, = {} ) #log "Monitoring job #{pid}" timeout = [:timeout] || 1024 signal = [:signal] || "TERM" status = wait_until_deadline( pid, Time.now.to_f + timeout ) return status if status #log "Job #{pid} is overdue, killing" ::Process.kill( signal, pid ) status = wait_until_deadline( pid, Time.now.to_f + 1 ) return status if status ::Process.kill( "KILL", pid ) if ! status dummy, status = wait2_now(pid) status end |
#wait_until_deadline(pid, deadline) ⇒ Object
5 6 7 8 9 10 11 12 13 14 15 16 |
# File 'lib/collective/utilities/process.rb', line 5 def wait_until_deadline( pid, deadline ) status = nil interval = 0.125 begin # execute at least once to get status dummy, status = wait2_now(pid) break if status #log "Waiting for #{pid}", "Sleeping #{interval}" if false sleep(interval) interval *= 2 if interval < 1.0 end while Time.now.to_f < deadline status end |