Thin不响应SIGINT或SIGTERM

时间:2011-06-23 15:47:49

标签: ruby linux thin sigint sigterm

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

  
    

使用机架适配器     瘦Web服务器(v1.2.11代号Bat-Shit Crazy)     最大连接数设置为1024     听取0.0.0.0:3111,CTRL + C停止         ^ C

  

Ctrl-C不执行任何操作(SIGINT)。也没有杀死(SIGTERM)。

我发现了一些对此行为的引用,但没有解决方案。问题似乎是在eventmachine(捆绑了最新的thin),ruby 1.9.2-r290或linux内核(Ubuntu 10.4 LTS,2.6.38.3-linode32)中。

它发生在我的项目中,但不是全新的rails项目。

参考文献:

1 个答案:

答案 0 :(得分:5)

我的猜测是,要么绑定EventMachine反应器循环阻止它退出,要么捕获SIGINT。

作为前者的一个简单示例,将其放入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运行)设置一个标志,表示已请求停止,该标记在reactor循环内被拾取。如果反应器回路卡在一个台阶上(如上例所示),那么它就不会退出。

所以有几个选择:

  1. 使用上面的解决方法来捕获SIGINT并强制退出。这可能会使连接处于不洁状态,但他们并没有将其称为 quick&amp; amp;脏了什么都没有;)

  2. 您可以将阻止代码放入线程或光纤中,这样可以使反应堆继续运行。

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

  4. 在您的实际代码中,这可能更难以跟踪,但查找生成线程并加入它们的任何位置,或大循环。当您尝试退出时,分析工具可以帮助显示正在运行的代码,最后您可以尝试禁用系统的各个部分和库来确定罪魁祸首的位置。