Ruby检查程序当前是否正在关闭

Ruby检查程序当前是否正在关闭,ruby,terminate,Ruby,Terminate,如何检查Ruby中的当前脚本是否正在关闭? 特别是,在程序关闭的情况下,我想将@reconnect设置为false,不再允许web套接字重新连接。我尝试了Signal.trap(“TERM”),但似乎不起作用 @reconnect是WebsocketClient类内的一个实例变量,我不能在类外的脚本中直接更改它 class WebsocketClient def ws_closed(event) $logger.warn "WS CLOSED" Signal.tr

如何检查Ruby中的当前脚本是否正在关闭? 特别是,在程序关闭的情况下,我想将
@reconnect
设置为
false
,不再允许web套接字重新连接。我尝试了
Signal.trap(“TERM”)
,但似乎不起作用

@reconnect
是WebsocketClient类内的一个实例变量,我不能在类外的脚本中直接更改它

class WebsocketClient
    def ws_closed(event)
      $logger.warn "WS CLOSED"
      Signal.trap("TERM") { 
        @stop = true
        @reconnect = false
      }

      unless $reauth
        if @stop
          EM.stop
        elsif @reconnect
          $logger.warn "Reconnecting..."
          EM.add_timer(@reconnect_after){ connect! }
        end
      end
    end
end

at_exit {
  $logger.fatal "Application terminated. Shutting down gracefully..."
  # ...
  # Do some exit work...
  # ...
  exit!
}
CTRL-C上的输出

01-02-2018 12:00:54.59  WARN    > WS CLOSED
01-02-2018 12:00:54.595 WARN    > Reconnecting...
01-02-2018 12:00:54.596 FATAL   > Application terminated. Shutting down gracefully..

见下文摘自我的答案,但似乎比其当前所附的问题更适合您的问题:

您的最佳选择可能比信号捕获要简单一些。
内核
模块
实际上为您提供了一个
#at_exit
方法,该方法将在程序实际退出之前执行

用法:(from)

“生产:”

如您所见,您可以定义多个处理程序,当程序退出时,这些处理程序将以相反的顺序执行

由于
内核
包含在
对象
中,因此您可以处理
对象
的细节,如

class People
  at_exit {puts "The #{self.name} have left"}
end
exit
# The People have left
甚至在实例上

p = People.new
p.send(:at_exit, &->{puts "We are leaving"})
# We are leaving
# The People have left
此外,对于更具体的基于
对象的实现,您可以查看

用法示例:

class Person
  def self.finalize(name)
    proc {puts "Goodbye Cruel World -#{name}"}
  end 
  def initialize(name)
    @name = name
    ObjectSpace.define_finalizer(self, self.class.finalize(@name))
  end
end
用法:

p = Person.new("engineersmnky")
exit
# Goodbye Cruel World -engineersmnky
这可能不是您特别想要的,因为当
对象
也被垃圾收集时(对于临时对象来说不是很好),这会触发,但是如果您的对象应该存在于整个应用程序中,那么这仍然可以像at_出口一样使用。范例

# requiring WeakRef to allow garbage collection 
# See: https://ruby-doc.org/stdlib-2.3.3/libdoc/weakref/rdoc/WeakRef.html
require 'weakref' # 
p1 = Person.new("Engineer")
p2 = Person.new("Engineer's Monkey")
p2 = WeakRef.new(p2)
GC.start # just for this example
# Goodbye Cruel World -Engineer's Monkey
#=> nil
p2
#=> WeakRef::RefError: Invalid Reference - probably recycled
exit
# Goodbye Cruel World -Engineer
正如您可以看到的那样,
p2
的定义终结器被触发,因为
人员已被gc删除,但程序尚未退出<代码>p1
的终结器一直等到退出时才启动,因为它在整个应用程序中保留其引用

p = Person.new("engineersmnky")
exit
# Goodbye Cruel World -engineersmnky
# requiring WeakRef to allow garbage collection 
# See: https://ruby-doc.org/stdlib-2.3.3/libdoc/weakref/rdoc/WeakRef.html
require 'weakref' # 
p1 = Person.new("Engineer")
p2 = Person.new("Engineer's Monkey")
p2 = WeakRef.new(p2)
GC.start # just for this example
# Goodbye Cruel World -Engineer's Monkey
#=> nil
p2
#=> WeakRef::RefError: Invalid Reference - probably recycled
exit
# Goodbye Cruel World -Engineer