我正在创建一个在EventMachine中运行Sinatra的应用程序,当我运行准系统测试应用程序时,我不能让服务器以Ctrl-C结束,我必须用-9或-usr2来杀死它。
我无法弄清楚为什么Sinatra报告它已停止但仍继续提供请求或为什么我无法使用Ctrl-C停止服务器。
使用Sinatra 1.4.4轻薄1.6.1停止消息但是继续
== Sinatra/1.4.4 has taken the stage on 4567 for development with backup from Thin
Thin web server (v1.6.1 codename Death Proof)
Maximum connections set to 1024
Listening on localhost:4567, CTRL+C to stop
Stopping ...
== Sinatra has ended his set (crowd applauds)
Ping!
^CPing!
Stopping ...
Ping!
^CStopping ...
这是我用来生成输出的准系统测试应用程序
# Run with 'ruby test.rb'
require 'eventmachine'
require 'sinatra/base'
require 'thin'
class NeverStops < Sinatra::Base
settings.logging = true
configure do
set :threaded, true
end
get '/foobar' do
'Foobar'
end
end
EM.run do
# Does nothing
#trap(:INT) { EM::stop(); exit }
#trap(:TERM) { EM::stop(); exit }
#trap(:KILL) { EM::stop(); exit }
EventMachine.add_periodic_timer 2 do
puts 'Ping!'
end
NeverStops.run!
end
降级Thin或Sinatra有不同的结果
薄的1.6.1与Sinatra 1.4.3没有停止的消息,但仍然不会死(防止死亡)
== Sinatra/1.4.3 has taken the stage on 4567 for development with backup from Thin
Thin web server (v1.6.1 codename Death Proof)
Maximum connections set to 1024
Listening on localhost:4567, CTRL+C to stop
Ping!
^CPing!
Stopping ...
Ping!
精简1.5.1与Sinatra 1.4.4只是STOPS
== Sinatra/1.4.4 has taken the stage on 4567 for development with backup from Thin
>> Thin web server (v1.5.1 codename Straight Razor)
>> Maximum connections set to 1024
>> Listening on localhost:4567, CTRL+C to stop
>> Stopping ...
== Sinatra has ended his set (crowd applauds)
使用Sinatra 1.4.3工作的精简1.5.1
== Sinatra/1.4.3 has taken the stage on 4567 for development with backup from Thin
>> Thin web server (v1.5.1 codename Straight Razor)
>> Maximum connections set to 1024
>> Listening on localhost:4567, CTRL+C to stop
Ping!
Ping!
Ping!
^C>> Stopping ...
== Sinatra has ended his set (crowd applauds)
我已经将我的宝石更新到最新版本,并尝试降级各种宝石,如EventMachine和Rack,看看我得到了什么结果,没有什么是有帮助的。
版本
答案 0 :(得分:2)
此问题特定于较新版本的Thin(请注意,v1.5.1不会出现此行为)。 1.6中引入了此行为,并记录了类似的问题here。 有问题的代码遵循上游issue中提到的相同模式。
TL;问题的DR版本: Thin将停止服务器,但不会停止反应器循环(因为它不会&#34;拥有&#34;反应堆)。允许Thin拥有其反应器循环是可能的,在这种情况下,您将恢复所需的行为(如1.5.1所示)。为了做到这一点,你必须在没有封闭EM#run { }
的情况下启动Thin,这将允许Thin启动(并随后拆除)反应器循环。
在这种情况下,可以想象周期性的&#34; ping&#34;作为一个单独的应用程序,与Thin共享reactor循环。他们都不能声称拥有反应堆回路。当Thin没有启动反应器时,Thin停止所有其他应用并退出反应器是错误的。然后,用户有责任根据需要处理信号并终止单个应用程序,最后停止反应器循环(导致进程退出)。
希望这个解释有所帮助!
答案 1 :(得分:-1)
Thin正在利用EM,你应该像使用Webrick和没有EM一样运行你的应用程序。示例config.ru:
require 'bundler'
Bundle.require
class UseToStop < Sinatra::Base
get '/foobar' { body "Foobar" }
end
run UseToStop
您确定需要此选项吗?这使事情变得复杂,并且是你需要的最后一件事。
set :threaded, true