In Ruby, I’m well aware that the most recently registered signal trapper is the one that takes precedence, so:
Signal.trap("TERM") {puts "foo"; exit}
Signal.trap("TERM") {puts "bar"; exit}
If I were to issue a ‘kill’ to the above script, it would print out “bar” and exit.
Is there a way, in Ruby itself, to enforce some sort of scope for trappers?
My specific situation is this:
We have an application that defines its own trapper (for this story, we’ll just say it only traps “TERM”) in a namespaced Signals module. That code is required into the app at runtime and pretty much left alone after that.
A 3rd-party gem (I won’t name names) we use, actually registers its own trapper for “TERM” in the initialize method, so the most recently initialized object will be the one to handle the “TERM” signal for the entire application with undesirable results…
While it may make sense for the 3rd party gems’ objects to have their own trappers defined, I don’t want them affecting my app.
Is anyone aware of a way to give the non-initialize-non-3rd-party trapper precedence without getting too fancy?
You could monkey patch
Signalto aliasSignal.trapand then replace it with a no-op:Then you can use
real_trapin your code and this rude unnamed gem you’re using will be ignored. You’d have to make sureSignalwas patched before your rude-gem did anything though.With that patch in place, sending a SIGTERM to this code:
would give you pancakes.
I generally try to avoid monkey patching but it is quite useful for kludging around bugs and other bad behavior.