[solid_queue] ワーカープロセス終了時のNoMethodError修正

rails/solid_queue

背景

Solid QueueのワーカープロセスがSIGTERMSIGKILLなどのシグナルで終了した際、status.exitstatusnilを返すケースがあります。このとき、条件式の演算子優先順位の問題によりNoMethodError: undefined method '>' for nilが発生していました。

この問題は、フォークされたワーカープロセスの終了状態を監視するForkSupervisorクラスで発生しており、プロセス管理の信頼性に影響を与えていました。

技術的な変更内容

問題のあったコード

変更前のコードでは、演算子の優先順位により意図しない評価順序になっていました。

if (terminated_fork = process_instances.delete(pid)) && !status.exited? || status.exitstatus > 0
  error = Processes::ProcessExitError.new(status)
  release_claimed_jobs_by(terminated_fork, with_error: error)
end

このコードは以下のように評価されます:

if ((terminated_fork = process_instances.delete(pid)) && !status.exited?) || (status.exitstatus > 0)

右辺のstatus.exitstatus > 0が単独で評価されるため、exitstatusnilの場合にNoMethodErrorが発生します。

修正後のコード

if (terminated_fork = process_instances.delete(pid)) && (!status.exited? || status.exitstatus.to_i > 0)
  error = Processes::ProcessExitError.new(status)
  release_claimed_jobs_by(terminated_fork, with_error: error)
end

修正のポイント:

  1. 括弧の追加: (!status.exited? || status.exitstatus.to_i > 0)を括弧で囲むことで、terminated_forkが存在する場合のみこの条件が評価されるようにしました
  2. to_iの使用: status.exitstatus.to_iとすることで、nilの場合は安全に0に変換されます

動作の違い

シグナルによるプロセス終了時のProcess::Statusの挙動:

# 通常の終了 (exit 1)
status.exited?     # => true
status.exitstatus  # => 1

# SIGTERMによる終了
status.exited?     # => false
status.exitstatus  # => nil
status.signaled?   # => true
status.termsig     # => 15 (SIGTERM)

修正後は、exitstatusnilの場合でもnil.to_iにより0となり、エラーを回避しつつ適切な処理フローを維持できます。

影響範囲

この修正により、以下のシナリオで安定性が向上します:

  • ワーカープロセスがシグナルで強制終了された場合
  • コンテナ環境でのグレースフルシャットダウン
  • システムリソース不足によるプロセスキル

修正はForkSupervisorreap_terminated_forksメソッドのみに限定されており、他のコンポーネントへの影響はありません。

記事メタデータ

Generated by:
Claude Sonnet 4.5 for DiffDaily

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
承認済み
Review Count:
1回
Reviewed by:
Gemini 2.5 Pro for DiffDaily

Review Criteria:

ガイドライン準拠 ✓ PASS

記事構成とDiffDaily Styleへの準拠状況

記事構成の3要素(Title, Context, Technical Detail)が明確に記載されています。また、コードブロック前後の空行やファイル名付きシンタックスハイライトなど、カスタムMarkdown構文も正しく使用されており、可読性が高いです。対象読者であるエンジニアに適切な技術レベルで書かれています。

  • 記事構成(Title、Context、Technical Detail)
  • DiffDaily Styleガイド準拠
  • カスタムMarkdown活用
  • 対象読者への適合性
技術的整合性 ✓ PASS

技術的な正確性と表現の適切性

Diffの内容を正確に反映しており、技術的な説明も論理的で正確です。演算子の優先順位という根本原因と、括弧と`.to_i`によるnil-safeな修正という解決策が的確に解説されています。`Process::Status`の挙動に関する補足説明も、問題の理解を深めるのに役立っています。

  • 技術用語の正確性
  • コード例の正確性
  • 説明の技術的正確性
PR内容との整合性 ✓ PASS

元のPR情報との一致度

PRのタイトル、説明、コード変更の意図を忠実に反映しており、ハルシネーションは見られません。PR番号やリポジトリ名などの固有名詞も正確です。PR情報から一歩進んで「影響範囲」を具体的に示した点も、読者の理解を助ける妥当な解説の範囲内です。

  • タイトル・説明の一致
  • Diff内容の正確な反映
  • 推測の排除