Sidekiqのタイムアウトについて調べる

Sidekiq では、デプロイ時などの SIGTERM を受けてから25秒(デフォルト値)以内に処理を完了しないとジョブがキューに押し戻されてしまう。

ECSにデプロイしている場合は、30 秒のタイムアウトで SIGKILL シグナルを送信するため、安全に Sidekiq をシャットダウンするなら、タイムアウトの秒数を30秒以内に収める必要がある。
そうしないと、実行中のジョブが kill されてしまう可能性がある。
タスクが停止すると、各コンテナのエントリプロセス (通常は PID 1) に SIGTERM シグナルを送信します。タイムアウトが経過すると、今度は SIGKILL シグナルをプロセスに送信します。デフォルトでは、SIGTERM シグナルの送信後 30 秒のタイムアウトで SIGKILL シグナルを送信します。

ジョブが25秒を超えてしまう場合の対策として
- 25秒以内に収まるようにジョブの単位を細かく分割する
- ECSの
stopTimeout
パラメータの値と、Sidekiq のtimeout
の値を伸ばす-
stopTimeout
パラメータは最大120秒まで設定できる
-

Sidekiq タイムアウト周りの記事は下記がとても参考になる

そもそもジョブをキューに押し戻さずに、全ての実行中のジョブの完了を待ってから、Sidekiq をシャットダウンする方法はないのか?
あるみたい

Sidekiq では TSTPシグナルを受け取ると「実行中のジョブはそのまま継続し、新規ジョブの実行を停止する」という挙動を行う

そもそも TERM とか TSTP ってなんだっけ?
- SIGKILL:強制終了
- SIGTERM:終了要求
- SIGTSTP:プロセスを一時停止、Ctrl + Z と同じ

Sidekiq でシグナルを受け取る部分のコードを見てみる
エントリポイント
シグナルのハンドリング
シグナルの挙動
TERM は raise Interrupt
で例外を発生させる
TSTP は cli.launcher.quiet
を実行する
quiet
新規ジョブの実行を停止する
@done
を true
にする

全ての実行中のジョブの完了を待ってから、Sidekiq をシャットダウンする検証
https://n8.hatenablog.com/entry/2015/05/01/100424 を参考に手元でも動かしてみる
スクリプト
# app/jobs/sample_job.rb
class SampleJob
include Sidekiq::Job
def perform
sleep 60
end
end
# lib/tasks/sample.rake
task sample: :environment do
SampleJob.perform_async
puts 'SampleJob enqueued'
sleep 10
ps = Sidekiq::ProcessSet.new
abort 'Sidekiq process not running' if ps.count.zero?
ps.first.quiet!
puts "TSTP sent\nWaiting 10sec for status update"
sleep 10
while (running_tasks = ps.first['busy']).positive?
puts "Waiting for tasks to finish. Num tasks: #{running_tasks}"
sleep 5
end
ps.first.stop!
puts 'SIGTERM sent'
end
ローカルで実行
# ターミナルA
bundle exec sidekiq -C config/sidekiq.yml
# ターミナルB
bin/rake sample
ログ
ターミナルA
Running via Spring preloader in process 71387
SampleJob enqueued
TSTP sent
Waiting 10sec for status update
Waiting for tasks to finish. Num tasks: 1
Waiting for tasks to finish. Num tasks: 1
Waiting for tasks to finish. Num tasks: 1
Waiting for tasks to finish. Num tasks: 1
Waiting for tasks to finish. Num tasks: 1
Waiting for tasks to finish. Num tasks: 1
Waiting for tasks to finish. Num tasks: 1
Waiting for tasks to finish. Num tasks: 1
Waiting for tasks to finish. Num tasks: 1
SIGTERM sent
ターミナルB
2025-03-19T06:06:19.749Z pid=71015 tid=1ns7 class=SampleJob jid=8deb6eaf269ad0a1b70d9070 INFO: start
2025-03-19T06:06:32.931Z pid=71015 tid=1ftb INFO: Received TSTP, no longer accepting new work
2025-03-19T06:06:32.931Z pid=71015 tid=1ftb INFO: Terminating quiet threads
2025-03-19T06:06:32.931Z pid=71015 tid=1ntr INFO: Scheduler exiting...
2025-03-19T06:07:20.340Z pid=71015 tid=1ns7 class=SampleJob jid=8deb6eaf269ad0a1b70d9070 elapsed=60.592 INFO: done
2025-03-19T06:07:28.010Z pid=71015 tid=1ftb INFO: Shutting down
2025-03-19T06:07:28.116Z pid=71015 tid=1ftb INFO: Bye!
ちゃんと全ての実行中のジョブの完了を待ってから、Sidekiq をシャットダウンできている 🎉