# バッチ設計書 45-worker

## 概要

本ドキュメントは、InvenTreeバックグラウンドワーカープロセス（Django-Q）を実行するinvokeタスク「worker」の設計書です。

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

**業務上の目的・背景**：InvenTreeは非同期タスク処理のためにDjango-Qフレームワークを使用しています。スケジュールされたタスク（定期バッチ処理）や非同期タスク（メール送信、レポート生成、通知等）を実行するために、バックグラウンドワーカープロセスが必要です。このバッチは、Django-Qのクラスタ管理コマンド（qcluster）を起動し、継続的にタスクキューを監視・実行します。

**バッチの実行タイミング**：システム起動時に常駐プロセスとして起動します。システムが稼働している間は継続的に実行されます。

**主要な処理内容**：
1. データベース接続の確立を待機（wait前処理）
2. Django-Qのqclusterコマンドを実行
3. タスクキュー（ORMブローカー）を監視
4. スケジュールされたタスクを定期的に実行
5. 非同期タスクをキューから取り出して処理
6. タスクの成功/失敗を記録

**前後の処理との関連**：wait（データベース接続待機）タスクが前処理として自動実行されます。InvenTreeの他の全てのスケジュールタスク（heartbeat, delete_successful_tasks, check_for_updates等）はこのworkerプロセスによって実行されます。

**影響範囲**：システム全体のバックグラウンド処理に影響します。workerが停止すると、スケジュールタスクや非同期タスクが実行されなくなります。

## バッチ種別

バックグラウンドワーカー / タスクスケジューラ

## 実行スケジュール

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

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| データベース接続 | データベースへの接続が確立されていること（wait前処理で確認） |
| Python環境 | 正しいPython仮想環境がアクティブであること |
| Django-Q設定 | Django-Qの設定が正しく構成されていること |
| 依存パッケージ | Django-Qパッケージがインストールされていること |

### 実行可否判定

waitタスクが成功した場合（データベース接続が確立された場合）にのみ実行されます。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| なし | - | - | - | このタスクは入力パラメータを受け取りません |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| django_q_schedule | DB | スケジュールされたタスクの定義 |
| django_q_ormq | DB | タスクキュー（ORMブローカー） |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| django_q_task | DB | 実行されたタスクの結果 |
| コンソール | テキスト | ワーカーの実行状況ログ |

### 出力ファイル仕様

ファイル出力はありません（データベースとコンソールへの出力のみ）。

## 処理フロー

### 処理シーケンス

```
1. wait実行（前処理）
   └─ データベース接続が確立されるまで待機

2. qclusterコマンド起動
   └─ Django-Qクラスタマネージャを起動

3. ワーカーループ（継続実行）
   ├─ スケジュールチェック
   │   └─ django_q_scheduleテーブルから実行すべきタスクを取得
   ├─ キュー監視
   │   └─ django_q_ormqテーブルから非同期タスクを取得
   └─ タスク実行
       └─ 取得したタスクを実行し、結果をdjango_q_taskに記録

4. シグナル処理
   └─ SIGTERM/SIGINT受信時にグレースフルシャットダウン
```

### フローチャート

```mermaid
flowchart TD
    A[worker開始] --> B[wait: DB接続待機]
    B --> C{DB接続OK?}
    C -->|No| D[接続待機継続]
    D --> C
    C -->|Yes| E[qcluster起動]
    E --> F[ワーカーループ開始]
    F --> G{シグナル受信?}
    G -->|No| H[スケジュールチェック]
    H --> I[キュー監視]
    I --> J{タスクあり?}
    J -->|Yes| K[タスク実行]
    J -->|No| L[待機]
    K --> M[結果記録]
    M --> F
    L --> F
    G -->|Yes| N[グレースフルシャットダウン]
    N --> O[worker終了]
```

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

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

| 処理 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| スケジュールチェック | django_q_schedule | SELECT | 実行すべきスケジュールタスクを取得 |
| キュー取得 | django_q_ormq | SELECT/DELETE | キューからタスクを取得・削除 |
| タスク結果記録 | django_q_task | INSERT | 実行結果を記録 |
| ハートビート | 各種システムテーブル | UPDATE | 定期的な状態更新 |

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

#### django_q_schedule

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | next_run | 現在時刻以前 | 実行すべきスケジュールを取得 |
| UPDATE | next_run | 次回実行時刻 | 実行後に更新 |

#### django_q_ormq

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | lock | ロックされていない | 利用可能なタスクを取得 |
| DELETE | - | 処理完了後 | キューから削除 |

#### django_q_task

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | name | タスク名 | タスク実行時 |
| INSERT | func | 実行関数名 | タスク実行時 |
| INSERT | result | 実行結果 | 成功/失敗に関わらず |
| INSERT | success | True/False | 実行結果 |
| INSERT | started | 開始時刻 | タスク開始時 |
| INSERT | stopped | 終了時刻 | タスク終了時 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | OperationalError | データベース接続失敗 | データベースサーバーの起動確認 |
| - | ConnectionError | ブローカー接続失敗 | ORM設定の確認 |
| - | TaskError | タスク実行中のエラー | タスクログを確認、個別タスクの修正 |
| - | ImportError | タスク関数のインポート失敗 | タスク定義の確認 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | タスク定義に依存（@scheduled_taskのretry設定） |
| リトライ間隔 | タスク定義に依存 |
| リトライ対象エラー | タスク関数内で発生した例外 |

### 障害時対応

1. ワーカー停止時：ログを確認し、原因を特定後に再起動
2. タスク失敗時：django_q_taskテーブルで失敗タスクを確認し、原因を調査
3. キュー滞留時：ワーカー数を増やすか、タスク処理を最適化
4. データベース接続断：データベースサーバーの復旧後、ワーカーを再起動

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | タスク単位 |
| コミットタイミング | 各タスク完了時 |
| ロールバック条件 | タスク実行中のエラー発生時 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | タスク発生頻度に依存 |
| 目標処理時間 | タスク内容に依存 |
| メモリ使用量上限 | 環境に依存（通常数百MB） |

## 排他制御

- 複数ワーカーインスタンスの同時実行は可能（スケーラビリティのため）
- タスクのロック機構により、同一タスクの重複実行を防止
- django_q_ormqテーブルのlock列で排他制御

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 起動ログ | ワーカー起動時 | クラスタ情報、ワーカーID |
| タスクログ | タスク実行時 | タスク名、実行時間、結果 |
| ハートビートログ | 定期的 | ワーカー状態 |
| エラーログ | エラー発生時 | エラー詳細とスタックトレース |
| シャットダウンログ | ワーカー停止時 | 終了メッセージ |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| ワーカープロセス稼働 | プロセス停止時 | システム管理者 |
| キュー滞留数 | 環境依存（100件以上等） | システム管理者 |
| タスク失敗率 | 環境依存（5%以上等） | システム管理者 |
| 処理時間 | タスクに依存 | システム管理者 |

## 備考

- `pre=[wait]`により、ワーカー起動前にデータベース接続待機が自動実行される
- `pty=True`オプションにより、ターミナル出力がリアルタイムで表示される
- Django-Qはデフォルトでデータベース（ORM）をブローカーとして使用
- スケジュールタスクはInvenTree各アプリで`@scheduled_task`デコレータにより定義
- monitorタスク（`invoke monitor`）でワーカーの状態を監視可能
- 本番環境では、システムサービス（systemd等）として登録し、自動起動・再起動を設定することを推奨
- 複数ワーカーを起動することで、タスク処理のスケーラビリティを向上可能
