# encoding: utf-8
#
require "xmlrpc/server"
$thread = Thread.new {
puts "Server starts"
rpcd = XMLRPC::Server.new
rpcd.serve
puts "Server stopped"
}
$thread.run
puts "Wait 30 seconds in main thread"
sleep 30
puts "Done"
안녕하세요.
XMLRPC 서버와 데이터 처리 작업을 한 프로세스 안에서 병행하기 위해 루비 프로그램을 설계하였고, 위의 코드처럼 메인과 XMLRPC서버를 돌리는 쓰레드로 나눠져있습니다.
만약에 SIGINT가 들어올 경우, 쓰레드에서 돌리던 서버와 메인 쓰레드가 한번에 (동시에는 어렵겠지만) 종료되어 셸로 돌아가는 것을 원하고 있습니다.
따라서 제가 예상하는 출력은 다음과 같습니다.
(셸에서 루비 코드를 실행)
Wait 30 seconds in main thread
Server starts
[2015-01-27 21:29:36] INFO WEBrick 1.3.1
[2015-01-27 21:29:36] INFO ruby 2.1.0 (2015-01-26) [x86_64-linux-gnu]
[2015-01-27 21:29:36] INFO WEBrick::HTTPServer#start: pid=6082 port=8080
^C
(Interrupt 예외에 대한 오류가 뜨거나, 소리 없이 셸로 돌아옴)
^C를 누르는 시점은 WEBrick이 완전히 가동된 시점입니다. 그러나, 제 가정과는 다르게 ^C는 WEBrick 만 종료시켰고, sleep 30은 계속 진행되고있었으며 다시 ^C를 눌러도 메인 쓰레드에는 전혀 영향을 주지 못하고 있었습니다.
해당 상황은 MRI 2.1.0과 2.2.0 양쪽에서 모두 발생하고 있습니다.
그러나 Rubinius 에서는 동작이 또 다릅니다. ^C를 WEBrick이 가동된 후에 누르면, sleep 30은 아무런 Exception 없이 중단되고 그 다음 코드인 puts "Done"가 실행되고 조용히 셸로 돌아옵니다.
ruby 2.2.0p0 (2014-12-25 revision 49005) [x86_64-linux]
rubinius 2.5.1 (2.1.0 8fd046f3 2015-01-26 3.5.1 JI) [x86_64-linux-gnu]
Signal.trap() 등을 사용해 SIGINT를 처리해보려고 했으나 상황에 진전이 없어서 루비 사용자 모임에 올리게 되었습니다.
MRI의 버그인지, 아니면 쓰레드 모델 때문에 제가 프로그램 구조를 바꿔야하는 상황인지 궁금합니다.