# バッチ設計書 1-queue:work

## 概要

本ドキュメントは、Laravelフレームワークのキューワーカーコマンド `queue:work` の設計仕様を記載したものです。本バッチはキューシステムの中核となるジョブ処理機能を提供します。

### 本バッチの処理概要

`queue:work` コマンドは、アプリケーションのキューに登録されたジョブを継続的に取り出し、デーモンプロセスとして処理を実行するバッチ処理です。

**業務上の目的・背景**：Webアプリケーションにおいて、メール送信、画像処理、外部API連携などの時間のかかる処理をリクエスト・レスポンスサイクルから切り離し、バックグラウンドで非同期実行することで、ユーザー体験の向上とシステムリソースの効率的な活用を実現します。キューワーカーは本番環境において常駐プロセスとして稼働し、登録されたジョブを順次処理する重要な役割を担います。

**バッチの実行タイミング**：システム起動時に開始し、継続的にデーモンとして稼働します。Supervisor等のプロセス管理ツールと組み合わせて使用されることが一般的です。

**主要な処理内容**：
1. 指定されたキュー接続からジョブを取得（ポーリング）
2. ジョブのペイロードを解析し、対応するジョブクラスをインスタンス化
3. ジョブのhandleメソッドを実行
4. 成功時はジョブを削除、失敗時はリトライまたは失敗ジョブテーブルに記録
5. メモリ使用量、実行時間、処理件数の監視と制限

**前後の処理との関連**：`queue:restart` コマンドによりグレースフルな再起動が可能です。失敗したジョブは `queue:retry` で再実行できます。`queue:pause` で一時停止、`queue:resume` で再開が可能です。

**影響範囲**：キューに登録された全てのジョブ、関連するデータベーステーブル（jobs, failed_jobs）、キャッシュ（再起動シグナル用）に影響を与えます。

## バッチ種別

ジョブ処理（キューワーカー）

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 常時稼働（デーモン） |
| 実行時刻 | システム起動時 |
| 実行曜日 | 該当なし |
| 実行日 | 該当なし |
| トリガー | 手動起動 / Supervisor等プロセス管理ツール |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| キュー接続設定 | config/queue.phpにて有効なキュー接続が設定されていること |
| キュードライバ | database, redis, sqs等のキュードライバが利用可能であること |
| キャッシュ設定 | 再起動シグナル検知のためキャッシュが設定されていること |

### 実行可否判定

- `--force` オプションが指定されていない場合、アプリケーションがメンテナンスモード中は処理をスキップ
- 指定されたキューが一時停止中（paused）の場合は処理を一時停止
- キャッシュに再起動シグナルが存在する場合は現在のジョブ完了後に終了

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| connection | string | No | config値 | キュー接続名 |
| --name | string | No | default | ワーカー名 |
| --queue | string | No | config値 | 処理対象のキュー名（カンマ区切りで複数指定可） |
| --once | bool | No | false | 1ジョブのみ処理して終了 |
| --stop-when-empty | bool | No | false | キューが空になったら終了 |
| --backoff | int | No | 0 | 例外発生時のリトライ待機秒数 |
| --max-jobs | int | No | 0 | 処理ジョブ数上限（0は無制限） |
| --max-time | int | No | 0 | 最大実行時間（秒、0は無制限） |
| --force | bool | No | false | メンテナンスモード中も実行 |
| --memory | int | No | 128 | メモリ上限（MB） |
| --sleep | int | No | 3 | ジョブがない場合のスリープ秒数 |
| --rest | int | No | 0 | ジョブ間の休止秒数 |
| --timeout | int | No | 60 | 子プロセスのタイムアウト秒数 |
| --tries | int | No | 1 | 失敗までのリトライ回数 |
| --json | bool | No | false | JSON形式で出力 |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| jobs テーブル | DB | データベースキュー使用時のジョブ格納先 |
| Redis キュー | Redis | Redisキュー使用時のジョブ格納先 |
| SQS キュー | AWS SQS | SQSキュー使用時のジョブ格納先 |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| 標準出力 | テキスト/JSON | ジョブ処理状況のログ |
| failed_jobs テーブル | DB | 失敗したジョブの記録 |

### 出力ファイル仕様

該当なし（ファイル出力は行わない）

## 処理フロー

### 処理シーケンス

```
1. 初期化処理
   └─ ワーカーインスタンスの生成、イベントリスナーの登録
2. メンテナンスモードチェック
   └─ --onceかつメンテナンスモード時はスリープして終了
3. キュー接続の取得
   └─ 引数またはconfig値からキュー接続を決定
4. デーモンループ開始
   └─ runWorkerメソッドでdaemonまたはrunNextJobを呼び出し
5. ジョブ取得
   └─ 指定キューからジョブをポップ
6. ジョブ実行
   └─ タイムアウトハンドラ登録後、ジョブを処理
7. 結果処理
   └─ 成功時は削除、失敗時はリトライまたは失敗記録
8. 継続判定
   └─ 終了条件（max-jobs, max-time, memory等）をチェック
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B{メンテナンスモード?}
    B -->|Yes & --once| C[スリープして終了]
    B -->|No or --force| D[イベントリスナー登録]
    D --> E[キュー接続取得]
    E --> F{--once指定?}
    F -->|Yes| G[runNextJob]
    F -->|No| H[daemon開始]
    H --> I{終了条件チェック}
    I -->|継続| J[ジョブ取得]
    J --> K{ジョブあり?}
    K -->|Yes| L[ジョブ実行]
    L --> M{成功?}
    M -->|Yes| N[ジョブ削除]
    M -->|No| O{リトライ可能?}
    O -->|Yes| P[キューに戻す]
    O -->|No| Q[失敗記録]
    N --> I
    P --> I
    Q --> I
    K -->|No| R[スリープ]
    R --> I
    I -->|終了| S[バッチ終了]
    G --> S
    C --> S
```

## データベース操作仕様

### 操作別データベース影響一覧

| 処理 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| ジョブ取得 | jobs | SELECT/DELETE | キューからジョブを取得 |
| ジョブ削除 | jobs | DELETE | 処理完了ジョブの削除 |
| 失敗記録 | failed_jobs | INSERT | 失敗ジョブの記録 |

### テーブル別操作詳細

#### jobs

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | id, queue, payload, attempts, reserved_at, available_at, created_at | available_at <= now() AND reserved_at IS NULL | 処理可能なジョブを取得 |
| UPDATE | reserved_at, attempts | 予約時刻と試行回数を更新 | ジョブ予約時 |
| DELETE | - | id指定 | ジョブ処理完了時 |

#### failed_jobs

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | uuid, connection, queue, payload, exception, failed_at | ジョブ情報と例外情報 | ジョブ失敗時 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| EXIT_ERROR (1) | 一般エラー | 予期しない例外発生 | ログ確認、原因調査 |
| EXIT_MEMORY_LIMIT (12) | メモリ超過 | メモリ使用量が上限超過 | ワーカー再起動 |
| - | タイムアウト | ジョブ処理がtimeoutを超過 | ジョブの最適化、timeout値の調整 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | --tries オプションで指定（デフォルト1回） |
| リトライ間隔 | --backoff オプションで指定（デフォルト0秒） |
| リトライ対象エラー | 全ての例外（ジョブ側でShouldBeUniqueUntilProcessing等の制御可能） |

### 障害時対応

1. プロセス異常終了時はSupervisor等により自動再起動
2. 失敗ジョブは `queue:retry` コマンドで再実行可能
3. メモリリーク疑いの場合は `--max-jobs` または `--max-time` で定期再起動

## トランザクション仕様

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | ジョブ単位（各ジョブの処理はアトミック） |
| コミットタイミング | ジョブ処理完了時 |
| ロールバック条件 | ジョブ処理中に例外発生時 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | アプリケーション依存（無制限） |
| 目標処理時間 | ジョブ依存（--timeoutで制限可能） |
| メモリ使用量上限 | 128MB（--memoryで変更可能） |

## 排他制御

- 同一キューに対して複数ワーカーの同時実行が可能
- データベースドライバ使用時はSELECT FOR UPDATE等で排他制御
- Isolatableインターフェースは未実装（複数インスタンス同時起動可能）

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 開始ログ | バッチ開始時 | Processing jobs from the [queue_name] queue |
| 進捗ログ | ジョブ処理中 | ジョブ名、ステータス（RUNNING/DONE/FAIL）、処理時間 |
| 終了ログ | バッチ終了時 | なし（デーモンのため通常終了しない） |
| エラーログ | エラー発生時 | ジョブ名、例外情報、スタックトレース |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| プロセス生存 | プロセス停止時 | Supervisor / プロセス監視ツール |
| メモリ使用量 | --memory オプション値 | 自動終了（再起動） |
| キューサイズ | queue:monitor で監視 | QueueBusyイベント |

## 備考

- `--daemon` オプションは非推奨（互換性のため残存）
- `--delay` オプションは非推奨、`--backoff` を使用
- JSON出力モード（`--json`）は構造化ログ出力に有用
- 本番環境ではSupervisor等でプロセス管理を推奨
