Ruby의 현재 script가 닫혀 있는지 어떻게 확인할 수 있습니까? 특히 프로그램이 종료되는 경우 @reconnect
를 false
로 설정하여 더 이상 웹소켓 재연결을 허용하지 않습니다. Signal.trap ( "TERM")
을 시도했지만 작동하지 않는 것 같습니다.
@reconnect
는 WebsocketClient class 내부의 인스턴스 변수이며 class 외부의 script에서 직접 변경할 수 없습니다.
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
Document )
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
보시다시피 Person
이 gc가되었지만 프로그램이 아직 종료되지 않았기 때문에 p2
에 대해 정의된 finalizer가 실행되었습니다. p1
의 finalizer는 애플리케이션 전체에서 참조를 유지했기 때문에 종료가 실행될 때까지 기다렸습니다.