Тонкий не отвечает на SIGINT или SIGTERM - PullRequest
5 голосов
/ 23 июня 2011

bundle exec thin start -p 3111 дает следующий вывод:

Использование стоечного адаптера Тонкий веб-сервер (кодовое имя 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).

Это происходит с моимпроект, но не с новым проектом рельсов.

Источники:

1 Ответ

5 голосов
/ 20 июля 2011

Я предполагаю, что либо что-то связывает петлю реактора 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) устанавливает флаг, по которому был запрошен останов, который принимается внутри контура реактора.Если петля реактора застряла на ступени (как в приведенном выше случае), то она не выйдет.

Итак, пара вариантов:

  1. использовать обходной путьвыше захвата SIGINT и форсирования выхода.Это может оставить соединения в нечистом состоянии, но они не называют это быстрая и грязная ни за что;)

  2. вы можете поместить код блокировки в потокили Fiber, который позволит реактору продолжать работу.

  3. ищите долгосрочные задачи или циклы внутри вашего кода и конвертируйте их для обработки EventMachine.em-http-request - это отличная библиотека для внешних http-запросов, и у em-synchrony есть несколько других протоколов (для соединений с базой данных, пулов соединений tcp и т. д.).В приведенном выше примере это просто: EventMachine.add_periodic_timer(1) { puts "EM Running" }

В вашем реальном коде это может быть сложнее отследить, но ищите места, где вы порождаете темы и присоединяетесь к ним,или большие петли.Инструмент профилирования может помочь показать, какой код выполняется, когда вы пытаетесь выйти, и, наконец, вы можете попытаться отключить различные части системы и библиотеки, чтобы выяснить, где виновник.

...