Комментарии 16
Привет, не очень понимаю смысла статьи, если у сайдкика есть API для работы с процессами. Был бы рад, если бы ты объяснил в чем преимущество твоего подхода :)
Я немного сбил вас с толку, называя запущенный воркер "сайдкик-процессом". Воркер работает внутри настоящего сайдкик-процесса и всю статью я пытаюсь остановить запущенный воркер, а процесс не трогать, так как ему еще предстоит обработать новые воркеры. API показывает как работать с запущенными процессами сайдкика, и команда #stop!
останавливает весь сайдкик процесс, а не отдельно запущенный воркер.
Вот разница при работе с процессами и в моем случае.
Сначала запустим процесс и вызовем метод stop!
, как это предлагают сайдкикеры.
INFO: Starting processing, hit Ctrl-C to stop
TestProcessWorker JID-e0d48711e21cd37c90e98186 INFO: start
# в этом месте я вызвал метод `stop!` на процессе из соседней вкладки
INFO: Shutting down
INFO: Terminating 49 quiet workers
INFO: Pausing up to 30 seconds to allow workers to finish...
WARN: Terminating 1 busy worker threads
WARN: Work still in progress [#<struct Sidekiq::BasicFetch::UnitOfWork queue="queue:default", message="{\"class\":\"TestProcessWorker\",\"args\":[1],\"retry\":false,\"queue\":\"default\",\"jid\":\"e0d48711e21cd37c90e98186\",\"created_at\":1469519195.722636,\"enqueued_at\":1469519195.722796}">]
INFO: Pushed 1 messages back to Redis
TestProcessWorker JID-e0d48711e21cd37c90e98186 INFO: fail: 121.278 sec
Повторный запуск сайдкика приводит к тому, что он пытается перезапустить процессы, которые были помечены статусом "fail".
Теперь давайте используем воркера из статьи и килять будем воркер, а не процесс:
INFO: Starting processing, hit Ctrl-C to stop
TestKillerWorker JID-e0d48711e21cd37c90e98186 INFO: start
# в этом месте кладем в редис соответствующий киллер-ключ
TestKillerWorker JID-e0d48711e21cd37c90e98186 INFO: done: 0.396 sec
Во втором случае процесс готов обрабатывать следующую задачу, в отличие от первого, где он вообще выключается со всеми работающими процессами.
Очень рад, что вы согласны выводами статьи. К большому сожалению лучшего способа, чем килять рядом запущенный тред, который знает, что его могут в любое время кильнуть, найдено не было. Может быть есть какие-нибудь идеи?
ну я для себя решил так, что если, допустим, воркер не идемпотентный (как того прям все требуют, но мы-то знаем, что это не всегда реально), то я просто выключаю конкретно ему ретрай и просто грохаю весь процесс сайдкика
Интересно, можно ли наподобие этого сделать механизм автоматического перезапуска всего процесса Sidekiq после выполнения тяжёлой по памяти задачи (чтобы вернуть память ОС, потому что та память, которую Ruby съел, он уже не отдаст до самой своей смерти)?
Сейчас у нас для этой задачи monit запряжён, рестартует sidekiq'а спустя полчаса после того, как тот станет потреблять больше полугига.
Для этого у сайдкика есть официальный API по работе с процессами, хотя я согласен с вами, что перезапуск извне выглядит эффективнее и надежнее.
Ruby отдаст все, кроме того, что было аллоцировано под новые Ruby Heaps. Писать код так, чтобы количество отъеденных RValues (от которого напрямую зависит размер локального хипа) — довольно просто, при некоторой сноровке.
https://blog.engineyard.com/2010/mri-memory-allocation-a-primer-for-developers — тоже полезно, чуть более прикладной вариант
http://stackoverflow.com/a/20608455/2035262 — совсем вкратце, мой ответ на SO про это
Надо бы заметку написать, но руки не доходят.
pipes? sockets? mmap?
> И в случае с руби лучше всего воспользоваться внешним механизмом передачи сообщений и редис в данном случае подойдет идеально.
> author: CTO at…
Рельсисты такие рельсисты…
Сайдкик-самоубийца