Ruby检查程序当前是否正在关闭
如何检查Ruby中的当前脚本是否正在关闭? 特别是,如果程序正在关闭,我想将@reconnect
设置为false
,不再允许web-socket重新连接。 我尝试过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..
请参阅以下从我的答案中获取的内容,但似乎与您目前所附的问题相关的问题更为贴切:
你最好的选择可能比信号陷阱更容易。 Kernel
Module
实际上为您提供了一个#at_exit
方法,该方法将在程序实际退出之前执行。
用法:(来自Kernel#at_exit
文档 )
def do_at_exit(str1) at_exit { print str1 } end at_exit { puts "cruel world" } do_at_exit("goodbye ") exit
“生产”
goodbye cruel world
如您所见,您可以定义多个处理程序,这些处理程序将在程序退出时以相反的顺序执行。
由于Kernel
包含在Object
您也可以处理Object
特性
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
此外,对于更具体的基于Object
的实现,您可以查看ObjectSpace.define_finalizer
。
用法示例:
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
这可能不是你想要的特别之处,因为当Object
被垃圾收集时也会触发(对于短暂的对象来说不是很好),但是如果你有整个应用程序中应该存在的对象,那么仍然可以使用类似于at_exit的对象。 例
# 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
终结器,因为Person
是gc’d但程序还没有退出。 p1
的终结器一直等到退出,因为它在整个应用程序中保留了它的引用。