# バッチ設計書 23-ping_machines

## 概要

本ドキュメントは、設定されたすべてのマシンに定期的にpingを送信しオンライン状態を確認するバッチ処理「ping_machines」の設計仕様を定義する。

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

このバッチは、InvenTreeシステムに登録されたマシン（外部機器・製造装置等）の稼働状態を定期的に監視し、オンライン/オフライン状態を把握することで、製造現場の機器管理と可用性監視を実現する。

**業務上の目的・背景**：製造環境において、外部マシンや装置との連携は生産活動の重要な要素である。マシンのオフライン状態を早期に検出することで、製造ラインの停止や作業遅延を最小限に抑えることができる。本バッチは、登録されたマシンの死活監視を自動化し、システム管理者や製造担当者が機器の状態を常に把握できるようにする。

**バッチの実行タイミング**：5分間隔でスケジュール実行される。Django-Qのスケジューラにより自動起動される。

**主要な処理内容**：
1. MACHINE_PING_ENABLED設定が有効かを確認
2. 有効な場合、登録されているすべてのマシンドライバを取得
3. 各ドライバに対してping_machines()メソッドを呼び出し
4. 各マシンの応答状態を確認・記録

**前後の処理との関連**：本バッチは独立して動作し、他のバッチとの直接的な依存関係はない。マシンレジストリ（machine.registry）と連携して動作する。

**影響範囲**：マシンテーブル（machineモジュール）の状態更新、ネットワーク通信への影響がある。

## バッチ種別

データ監視 / ヘルスチェック

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 5分間隔 |
| 実行時刻 | 5分ごと |
| 実行曜日 | 毎日（常時） |
| 実行日 | 毎日（常時） |
| トリガー | Django-Q ScheduledTask.MINUTES, 5 |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| データベース接続 | InvenTreeデータベースに正常に接続できること |
| Django-Qワーカー稼働 | バックグラウンドワーカーが稼働していること |
| マシンデータ存在 | マシンレジストリにドライバが登録されていること |
| ネットワーク接続 | マシンへのネットワーク接続が可能であること |

### 実行可否判定

- `MACHINE_PING_ENABLED` グローバル設定がTrue（デフォルトTrue）の場合のみ実行
- 設定がFalseの場合は即座にreturnして処理をスキップ

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| なし | - | - | - | 本バッチは入力パラメータを受け取らない |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| machine.registry | Registry | マシンドライバレジストリ |
| common_inventreesetting | DB | MACHINE_PING_ENABLED設定 |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| マシン状態 | Memory/DB | 各マシンのオンライン状態 |
| ログ | Log | pingの実行結果ログ |

### 出力ファイル仕様

本バッチはファイル出力を行わない。

## 処理フロー

### 処理シーケンス

```
1. MACHINE_PING_ENABLED設定の確認
   └─ get_global_setting('MACHINE_PING_ENABLED', True)
2. 設定が無効な場合は即座に終了
   └─ return
3. 登録されているすべてのマシンドライバを取得
   └─ registry.get_drivers()
4. 各ドライバに対してpingを実行
   └─ driver.ping_machines()
5. デバッグログに実行結果を記録
   └─ logger.debug("Pinging machines for driver '%s'", driver.SLUG)
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B{MACHINE_PING_ENABLED?}
    B -->|無効| C[バッチ終了]
    B -->|有効| D[全ドライバを取得]
    D --> E{ドライバあり?}
    E -->|なし| C
    E -->|あり| F[各ドライバでpingを実行]
    F --> G[デバッグログ出力]
    G --> H{次のドライバあり?}
    H -->|あり| F
    H -->|なし| C
```

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

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

| 処理 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 設定取得 | common_inventreesetting | SELECT | MACHINE_PING_ENABLED設定の取得 |
| マシン状態更新 | 各ドライバ依存 | UPDATE | マシンのオンライン状態更新（ドライバ実装依存） |

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

#### common_inventreesetting

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | key | = 'MACHINE_PING_ENABLED' | ping機能の有効/無効判定 |
| SELECT | value | - | デフォルトTrue |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | NetworkError | マシンへの接続失敗 | ログ出力、次のマシンへ継続 |
| - | TimeoutError | ping応答タイムアウト | ログ出力、次のマシンへ継続 |
| - | DriverError | ドライバの初期化失敗 | ログ出力、処理継続 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 各ドライバの実装に依存 |
| リトライ間隔 | 各ドライバの実装に依存 |
| リトライ対象エラー | ネットワークエラー、タイムアウト |

### 障害時対応

個別のマシンへのping失敗は他のマシンの監視に影響しない。継続的な失敗はマシンのオフライン状態として記録される。

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | 各ドライバのping処理ごと |
| コミットタイミング | 各ping処理完了時 |
| ロールバック条件 | 個別ping処理でのエラー発生時 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 数台〜数十台のマシン |
| 目標処理時間 | 5分以内（次回実行までに完了） |
| メモリ使用量上限 | 通常のDjangoプロセス制限内 |

## 排他制御

同時実行の制御はDjango-Qのスケジューラに委ねられている。5分間隔での実行のため、前回の実行が完了していない場合は重複実行の可能性がある。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 開始ログ | バッチ開始時 | Django-Qによる自動ログ |
| デバッグログ | 各ドライバping実行時 | "Pinging machines for driver '{SLUG}'" |
| 終了ログ | バッチ終了時 | Django-Qによる自動ログ |
| エラーログ | エラー発生時 | エラー詳細、スタックトレース |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| 処理時間 | 5分（次回実行前に完了） | システム管理者 |
| マシンオフライン | 連続失敗回数 | システム管理者（ドライバ実装依存） |

## 備考

- 本バッチは `@scheduled_task(ScheduledTask.MINUTES, 5)` デコレータにより5分間隔で実行される
- `MACHINE_PING_ENABLED` 設定により機能のON/OFFが可能（デフォルトはON）
- OpenTelemetry によるトレーシングが有効化されている（`@tracer.start_as_current_span`）
- 実際のping処理は各ドライバの `ping_machines()` メソッドに委譲される
- ログレベルはデバッグレベル（logger.debug）を使用し、通常運用時のログ量を抑制
