At_exit handlers and Process.kill

Hi all,

Ruby 1.8.6 p114
OS X 10.4

None of these handlers get picked up when I kill the ‘process_test.rb’
program with an external program. Why not?

process_test.rb

File.open(“pid.txt”, “w”){ |fh| fh.print Process.pid }
p Process.pid

sleep 1 while true

at_exit {
puts “AT_EXIT”
}

END{
puts “END”
}

trap(“KILL”){
puts “KILLED”
}

kill_test.rb

pid = IO.read(“pid.txt”).to_i
p pid
Process.kill(5, pid)

Dan

Daniel B. wrote:

Hi all,

Ruby 1.8.6 p114
OS X 10.4

None of these handlers get picked up when I kill the ‘process_test.rb’
program with an external program. Why not?

I had to use all of them:

Signal.trap(“KILL”) { }
Signal.trap(“EXIT”) { }
Signal.trap(“TERM”) { }
Signal.trap(“ABRT”) { }

Use Signal.list to get a list of available signals to trap on you
machine.

On Apr 15, 7:25 am, Tomek P. [email protected] wrote:

Signal.trap(“KILL”) { }
Signal.trap(“EXIT”) { }
Signal.trap(“TERM”) { }
Signal.trap(“ABRT”) { }

Use Signal.list to get a list of available signals to trap on you machine.

Ok, what about the at_exit handler?

Thanks,

Dan

Daniel B. wrote:

process_test.rb

File.open(“pid.txt”, “w”){ |fh| fh.print Process.pid }
p Process.pid

sleep 1 while true

you really think that the following line will be executed ?

puts "KILLED"

}

kill_test.rb

pid = IO.read(“pid.txt”).to_i
p pid
Process.kill(5, pid)

This is SIGTRAP

Guy Decoux

Daniel B. wrote:

sleep 1 while true
you really think that the following line will be executed ?

Why not?

Try this

ruby -e ‘sleep 1 while true; p :ok’

and wait that it give :ok …

Guy Decoux

ts wrote:

and wait that it give :ok …

Yes, Guy, I understand that. You aren’t listening.

How do I create an all purpose cleanup handler within a Ruby program
that will fire off no matter how the script is terminated?

Thanks,

Dan

ts wrote:

Daniel B. wrote:

process_test.rb

File.open(“pid.txt”, “w”){ |fh| fh.print Process.pid }
p Process.pid

sleep 1 while true

you really think that the following line will be executed ?

Why not? The docs say at_exit, “Converts block to a Proc object (and
therefore binds it at the point of call), and registers
it for execution when the program exits.”

Well, the program exited, didn’t it?

If this just can’t work then I think there needs to be a way to handle
graceful cleanup without having to trap all the possible signals that
could kill the program.

Regards,

Dan

On Apr 15, 2008, at 6:58 AM, Daniel B. wrote:

p Process.pid

This works for me on OS 10.5.2 and ruby-1.8.6-p111

$ cat runner.rb
File.open(‘pid.txt’, ‘w’) {|fd| fd.puts Process.pid}
puts Process.pid

at_exit {$stderr.puts “AT_EXIT”}
END {$stderr.puts “END”}
Signal.trap(5) {$stderr.puts “KILLED”}

loop {sleep 1}

$ cat killer.rb
pid = Integer(File.read(‘pid.txt’))
puts pid

Process.kill(5,pid)

And when I run the killer script the runner script dies and outputs
“KILLED” to stderr.

The only real difference was using the explicit signal number (5) and
putting the infinite sleep after all the exit handlers were
registered. The only handler that was run was the block handling the
trap. But the END block and the at_exit block were not run. I would
expect that since a sigkill is pretty severe.

Blessings,
TwP

Daniel B. wrote:

How do I create an all purpose cleanup handler within a Ruby program
that will fire off no matter how the script is terminated?

at_exit and trap the signal that you want but please do this
before ‘sleep 1 while true’

moulon% ruby -e ‘at_exit { puts :exit}; trap(“TRAP”) { puts :SIGTRAP;
exit }; sleep 1 while true’
SIGTRAP
exit
moulon%

Guy Decoux

On Tue, 15 Apr 2008 08:35:35 -0500, Daniel B. wrote:

I had to use all of them:

Signal.trap(“KILL”) { }
Signal.trap(“EXIT”) { }
Signal.trap(“TERM”) { }
Signal.trap(“ABRT”) { }

Use Signal.list to get a list of available signals to trap on you
machine.

Ok, what about the at_exit handler?

It will work if you put things in the right order. (See my other
answer.)

–Ken

Ken B. wrote:

therefore binds it at the point of call), and registers it for execution
when the program exits."

Ruby does everything in the order it encounters it in the file.
at_exit installs an exit handler, (a proc to be run later) but it’s a
method that has to be executed. If you put “sleep 1 while true” before
the at_exit call, the at_exit call will never be executed, so the exit
handler will never be installed. Adjust your program to call at_exit (or
whatever other handlers you want) before running anything else.

Note that you can use BEGIN to register handlers out of order:

exit

BEGIN {
at_exit { puts “at_exit” }
END { puts “END” }
}

(without the BEGIN, nothing is printed)

On Tue, 15 Apr 2008 11:28:33 -0500, Daniel B. wrote:

therefore binds it at the point of call), and registers it for execution
when the program exits."

Ruby does everything in the order it encounters it in the file.
at_exit installs an exit handler, (a proc to be run later) but it’s a
method that has to be executed. If you put “sleep 1 while true” before
the at_exit call, the at_exit call will never be executed, so the exit
handler will never be installed. Adjust your program to call at_exit (or
whatever other handlers you want) before running anything else.

process_test.rb

at_exit {
puts “AT_EXIT”
}

END{
puts “END”
}

trap(“KILL”){
puts “KILLED”
}

File.open(“pid.txt”, “w”){ |fh| fh.print Process.pid }
p Process.pid

sleep 1 while true

–Ken

On Apr 15, 2008, at 10:58 AM, Daniel B. wrote:

Yes, Guy, I understand that. You aren’t listening.

How do I create an all purpose cleanup handler within a Ruby program
that will fire off no matter how the script is terminated?

Thanks,

cleanup = lambda {
next if $cleanup_was_already_done
$cleanup_was_already_done = true

your cleanup code goes here

}

Signal.list.values.each do |signal|
Signal.trap(signal,&cleanup)
end

at_exit &cleanup

Blessings,
TwP

Tim P. wrote:

process_test.rb

puts “END”

END {$stderr.puts “END”}

Blessings,
TwP

Were you able to get at_exit or END to fire off with other signals?

Thanks,

Dan

Ken B. wrote:

therefore binds it at the point of call), and registers it for execution
at_exit {

File.open(“pid.txt”, “w”){ |fh| fh.print Process.pid }
p Process.pid

sleep 1 while true

Right, I should have clarified that, even with the right ordering,
at_exit and END blocks weren’t called.

Perhaps it’s the signal I used? I haven’t fully experimented yet…

Regards,

Dan

On Tue, 15 Apr 2008 12:29:01 -0500, Daniel B. wrote:

Why not? The docs say at_exit, "Converts block to a Proc object (and

process_test.rb

}

Regards,

Dan

See signal(7) for descriptions and numbers of the various signals. Most
likely you want to use SIGINT (signal 1), and then at_exit will be
sufficient. Note that SIGKILL (signal 9) cannot be caught under any
circumstances (it’s used to kill badly misbehaving applications), so
your
sigkill handler is useless.

I think it’s unnecessary to install lots of signal handlers to do the
cleanup. Just learn what each signal does, and what to expect, and
at_exit should already be designed to do what you want.

–Ken

Ken B. wrote:

so the exit handler will never be installed. Adjust your program to
}
Right, I should have clarified that, even with the right ordering,
likely you want to use SIGINT (signal 1), and then at_exit will be
SIGINT is 2, 1 is SIGHUP

On Apr 15, 2008, at 11:29 AM, Daniel B. wrote:

Perhaps it’s the signal I used? I haven’t fully experimented yet…

only -9 works in windows

a @ http://codeforpeople.com/

Joel VanderWerf wrote:

Why not? The docs say at_exit, "Converts block to a Proc object (and
Note that you can use BEGIN to register handlers out of order:

exit

BEGIN {
at_exit { puts “at_exit” }
END { puts “END” }
}

(without the BEGIN, nothing is printed)

Ah, yes. I think between this and Tim’s all purpose catcher, we have the
makings of a nice little library. :slight_smile:

Many thanks,

Dan

On Apr 15, 2008, at 11:25 AM, Tim P. wrote:

cleanup = lambda {
next if $cleanup_was_already_done
$cleanup_was_already_done = true

your cleanup code goes here

}

Signal.list.values.each do |signal|
Signal.trap(signal,&cleanup)
end

cleanup = lambda do
cleanup = lambda{}
p ‘cleanup’
end

a @ http://codeforpeople.com/

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs