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 Signal to alias Signal.trap and then replace it with a no-op:
module Signal
class << self
alias_method :real_trap, :trap
def trap(*) end
end
end
Then you can use real_trap in your code and this rude unnamed gem you're using will be ignored. You'd have to make sure Signal was patched before your rude-gem did anything though.
With that patch in place, sending a SIGTERM to this code:
Signal.trap("TERM") {puts "foo"; exit}
Signal.trap("TERM") {puts "bar"; exit}
Signal.real_trap("TERM") {puts "pancakes"; exit}
would give you pancakes.
I generally try to avoid monkey patching but it is quite useful for kludging around bugs and other bad behavior.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With