# 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.
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
···
On Apr 15, 2008, at 6:58 AM, Daniel Berger 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?
# 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)
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 Tue, 15 Apr 2008 11:28:33 -0500, Daniel Berger wrote:
ts wrote:
Daniel Berger 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."
--
Ken (Chanoch) Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology. http://www.iit.edu/~kbloom1/
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
Were you able to get at_exit or END to fire off with other signals?
Use Signal.list to get a list of available signals to trap on you
machine.
Ok, what about the at_exit handler?
--
Ken (Chanoch) Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology. http://www.iit.edu/~kbloom1/
# 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."
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 Berger wrote:
--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407
On Tue, 15 Apr 2008 11:28:33 -0500, Daniel Berger wrote:
ts wrote:
Daniel Berger 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."
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
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...
# 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."
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)
Ah, yes. I think between this and Tim's all purpose catcher, we have the makings of a nice little library.
Many thanks,
Dan
···
On Tue, 15 Apr 2008 11:28:33 -0500, Daniel Berger wrote:
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
···
On Tue, 15 Apr 2008 12:29:01 -0500, Daniel Berger wrote:
Ken Bloom wrote:
On Tue, 15 Apr 2008 11:28:33 -0500, Daniel Berger wrote:
ts wrote:
Daniel Berger 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."
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
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
--
Ken (Chanoch) Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology. http://www.iit.edu/~kbloom1/
# 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."
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
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
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
SIGINT is 2, 1 is SIGHUP
···
On Tue, 15 Apr 2008 12:29:01 -0500, Daniel Berger wrote:
On Tue, 15 Apr 2008 11:28:33 -0500, Daniel Berger wrote:
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.
That's not going to work. The various exit handlers already have a reference to the cleanup proc, so reassigning the cleanup variable will not prevent it from getting called twice. I know that global variables are ugly, but there is a time and a place for everything.
And it's way too clever for me
TwP
···
On Apr 15, 2008, at 7:10 PM, ara.t.howard wrote:
On Apr 15, 2008, at 11:25 AM, Tim Pease 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
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
That's not going to work. The various exit handlers already have a reference to the cleanup proc, so reassigning the cleanup variable will not prevent it from getting called twice. I know that global variables are ugly, but there is a time and a place for everything.
And it's way too clever for me
--
we can deny everything, except that we have the possibility of being better. simply reflect on that.
h.h. the 14th dalai lama