Я предполагаю, что либо что-то связывает петлю реактора 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
) устанавливает флаг, по которому был запрошен останов, который принимается внутри контура реактора.Если петля реактора застряла на ступени (как в приведенном выше случае), то она не выйдет.
Итак, пара вариантов:
использовать обходной путьвыше захвата SIGINT и форсирования выхода.Это может оставить соединения в нечистом состоянии, но они не называют это быстрая и грязная ни за что;)
вы можете поместить код блокировки в потокили Fiber, который позволит реактору продолжать работу.
ищите долгосрочные задачи или циклы внутри вашего кода и конвертируйте их для обработки EventMachine.em-http-request - это отличная библиотека для внешних http-запросов, и у em-synchrony есть несколько других протоколов (для соединений с базой данных, пулов соединений tcp и т. д.).В приведенном выше примере это просто: EventMachine.add_periodic_timer(1) { puts "EM Running" }
В вашем реальном коде это может быть сложнее отследить, но ищите места, где вы порождаете темы и присоединяетесь к ним,или большие петли.Инструмент профилирования может помочь показать, какой код выполняется, когда вы пытаетесь выйти, и, наконец, вы можете попытаться отключить различные части системы и библиотеки, чтобы выяснить, где виновник.