我的 block/yield 如何传递变化的变量?

How can my block/yield pass a changing variable?

我正在编写以下模块来捕获 SIGTERM,它偶尔会发送给我的延迟作业工作人员,并设置一个名为 term_now 的变量,让我的作业在完成之前优雅地自行终止。

如果我将以下代码放入我的工作中,我的模块中的以下代码将完美运行,但我需要它用于多个工作,当我将它放入模块中时它不起作用。

我认为它不起作用,因为它只通过 term_now 一次(当它为 false 时),即使它 returns 为真它也不会再次通过它,因此它永远不会停止工作。

module StopJobGracefully

  def self.execute(&block)
    begin
      term_now = false
      old_term_handler = trap('TERM') do
        term_now = true
        old_term_handler.call
      end

      yield(term_now)
    ensure
      trap('TERM', old_term_handler)
    end
  end

end

这是正常使用的工作内联代码(这是我试图转换为模块的代码):

class SMSRentDueSoonJob

  def perform
    begin
      term_now = false
      old_term_handler = trap('TERM') do 
        term_now = true 
        old_term_handler.call
      end

      User.find_in_batches(batch_size: 1000) do

        if term_now
          raise 'Gracefully terminating job early...'
        end

        # do lots of complicated work here
      end

    ensure
      trap('TERM', old_term_handler)
    end
  end

end

你基本上是自己回答的。在您提供的示例代码中,term_now 仅在调用 yield 之前捕获陷阱时才会变为真。

你需要做的是提供一种周期性获取信息的机制,这样你就可以在ie find_in_batches.

的运行中进行检查

因此,您的模块应该有一个 term_now 方法,而不是产生结果,该方法可能 return 一个实例变量 @term_now.