Ruby Signal Trapper优先级

时间:2012-10-23 21:41:29

标签: ruby linux signals

在Ruby中,我很清楚最近注册的信号捕获器是优先的,所以:

Signal.trap("TERM") {puts "foo"; exit}
Signal.trap("TERM") {puts "bar"; exit}

如果我要对上面的脚本发出'kill',它会打印出“bar”并退出。

在Ruby本身中,是否有办法为捕获者强制实施某种范围?

我的具体情况如下:

我们有一个应用程序定义了自己的捕获器(对于这个故事,我们只是说它只捕获“TERM”)在命名空间的信号模块中。该代码在运行时需要进入应用程序,之后几乎不用了。

我们使用的第三方gem(我不会命名名称),实际上在初始化方法中为“TERM”注册了自己的捕获器,因此最近初始化的对象将是一个处理整个应用程序的“TERM”信号,结果不理想......

虽然第三方宝石的对象定义了自己的捕手可能有意义,但我不希望它们影响我的应用。

是否有人知道如何让非初始化非第三方捕手优先而不会过于花哨?

1 个答案:

答案 0 :(得分:3)

您可以将Signal修补程序添加到别名Signal.trap,然后将其替换为no-op:

module Signal
    class << self
        alias_method :real_trap, :trap
        def trap(*) end
    end
end

然后你可以在代码中使用real_trap,这个粗俗的未命名的宝石将会被忽略。你必须确保在你的粗鲁宝石做任何事情之前修补了Signal

使用该补丁,将SIGTERM发送到此代码:

Signal.trap("TERM") {puts "foo"; exit}
Signal.trap("TERM") {puts "bar"; exit}
Signal.real_trap("TERM") {puts "pancakes"; exit}

会给你煎饼。

我通常会尽量避免猴子修补,但它对于克服错误和其他不良行为非常有用。