瘦不响应SIGINT或SIGTERM

bundle exec thin start -p 3111提供以下输出:

使用机架适配器Web服务器(V1.2.11代号蝙蝠狗屎疯狂)最大连接设置为1024聆听0.0.0.0:3111,CTRL + C停止^ C

Ctrl-C不做任何事情(SIGINT)。 也不杀(SIGTERM)。

我发现了一些这种行为的参考,但没有解决scheme。 这个问题似乎是在eventmachine(捆绑在最新的精简版)中,在ruby 1.9.2-r290中,或者在linux内核(Ubuntu 10.4 LTS,2.6.38.3-linode32)中。

它发生在我的项目上,但不是一个全新的铁路项目。

参考文献:

  • http://groups.google.com/group/thin-ruby/browse_thread/thread/4b7c28e8964b5001?fwc=2

Solutions Collecting From Web of "瘦不响应SIGINT或SIGTERM"

我的猜测是,有些东西是绑定EventMachine的反应器循环阻止它退出,或者是什么东西的陷阱信号。

作为前者的一个简单的例子,把这个到config.ru和运行与thin -p 4567 start

 require 'thin' require 'sinatra' require 'eventmachine' get '/' do "hello world" end run Sinatra::Application EventMachine.schedule do trap("INT") do puts "Caught SIGINT" EventMachine.stop # this is useless # exit # this stops the EventMachine end i = 0 while i < 10 puts "EM Running" i += 1 sleep 1 end end 

如果不捕获SIGINT,就会得到与捕获它并调用EM.stop相同的行为。 EM.stop(至少在纯ruby版本中,可以使用EVENTMACHINE_LIBRARY="pure_ruby" thin start )设置一个标志,表示已经请求了一个停止,该停止在反应器循环内部被拾取。 如果反应器回路卡在一个步骤(如上面的情况),那么它不会退出。

所以有几个选择:

  1. 使用上面陷阱SIGINT和强制退出的解决方法。 这可能导致不洁净状态的联系,但他们不称之为快速和肮脏的东西;)

  2. 你可以把阻塞代码放入一个线程或一个光纤中,这样可以让反应堆继续运行。

  3. 寻找长时间运行的任务或循环内的代码,并将其转换为EventMachine感知。 em-http-request是一个很好的外部http请求库,em-synchrony还有其他一些协议(用于数据库连接,tcp连接池等)。 在上面的例子中,这很简单: EventMachine.add_periodic_timer(1) { puts "EM Running" }

在你的实际代码中,这可能很难追查,但是寻找你产生线程并加入它们的地方,或者是大的循环。 分析工具可以帮助显示当您尝试退出时正在运行的代码,最后,您可以尝试禁用系统和库的各个部分来确定罪魁祸首的位置。