# 機能設計書 24-タイマートリガー

## 概要

本ドキュメントは、Jenkinsのタイマートリガー（TimerTrigger）機能の設計仕様を定義する。タイマートリガーは、cronスケジュールに基づいてジョブを定期的に実行するためのトリガー機構を提供する。

### 本機能の処理概要

タイマートリガーは、設定されたcronスケジュールに従って、SCMの変更有無に関係なくジョブを定期的に実行する機能である。

**業務上の目的・背景**：定期的なタスク実行（ナイトリービルド、定期テスト、バッチ処理等）は多くのCI/CD環境で必要とされる。タイマートリガーは、時間ベースでジョブをスケジュール実行するためのシンプルで信頼性の高いメカニズムを提供する。

**機能の利用シーン**：
- ナイトリービルドの実行（毎日深夜にフルビルド）
- 定期的な回帰テストの実行
- 週次/月次のレポート生成
- 定期的なデプロイメントジョブ
- システム監視・ヘルスチェック

**主要な処理内容**：
1. cronスケジュールの解析と次回実行時刻の計算
2. 指定時刻でのビルドトリガー
3. H（ハッシュ）シンタックスによるジョブごとの実行時間分散
4. ビルド原因（Cause）の記録

**関連システム・外部連携**：Triggerシステム、ビルドキュー、cronスケジューラーとの連携。

**権限による制御**：ジョブの設定権限を持つユーザーがタイマートリガーの設定を変更可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 12 | ジョブ設定 | 主画面 | タイマートリガーの設定・編集 |

## 機能種別

トリガー / 時間スケジュール

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| spec | String | Yes | cronスケジュール指定 | 有効なcron構文 |

### 入力データソース

ジョブ設定画面からの設定値。cronスケジュールはHash関数を使用してジョブごとに分散される。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ビルドジョブ | Queue.Item | キューに追加されたビルドジョブ |
| TimerTriggerCause | Cause | ビルド原因の記録 |

### 出力先

ビルドキューへのジョブ追加。

## 処理フロー

### 処理シーケンス

```
1. Cron.doRun() が毎分実行
   └─ Trigger.checkTriggers(Calendar) を呼び出し
2. CronTabList.check(Calendar) でスケジュール判定
   └─ 現在時刻がcronパターンにマッチするか確認
3. マッチした場合、TimerTrigger.run() 実行
   └─ project.scheduleBuild(TimerTriggerCause) でビルドをスケジュール
```

### フローチャート

```mermaid
flowchart TD
    A[cronスケジュール一致チェック] --> B{tabs.check成功?}
    B -->|Yes| C[TimerTrigger.run]
    B -->|No| D[スキップ]
    C --> E[project.scheduleBuild]
    E --> F[TimerTriggerCause作成]
    F --> G[ビルドキュー追加]
    G --> H[完了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | ハッシュ分散 | Hシンタックスでジョブ名に基づいた時間分散を推奨 | cronスケジュール設定時 |
| BR-002 | タイムゾーン | Jenkinsマスターのシステムタイムゾーンに基づく | 全スケジュール判定時 |
| BR-003 | ビルド重複 | 同一ジョブが既にビルド中でも新規ビルドがキューに追加される | ビルドスケジュール時 |

### 計算ロジック

```java
// cronスケジュールの標準形式
// 分 時 日 月 曜日
// 例: "0 2 * * *" = 毎日午前2時

// Hシンタックスによる分散
// "H H(0-7) * * *" = ジョブ名のハッシュに基づき0-7時の間でランダム
Hash hash = Hash.from(job.getFullName());
CronTabList tabs = CronTabList.create(spec, hash);
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 設定保存 | config.xml | INSERT/UPDATE | タイマートリガー設定の永続化 |

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

#### config.xml（ジョブ設定ファイル）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT/UPDATE | triggers/hudson.triggers.TimerTrigger | spec値 | XMLシリアライズ |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | IllegalArgumentException | 無効なcronスケジュール | 設定時にエラー表示 |
| - | RuntimeException | run()実行中の例外 | ログ記録、他のトリガー処理を続行 |

### リトライ仕様

リトライは行わない。次回のcronスケジュールで再度チェックが行われる。

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

トランザクション管理はない。ビルドのキュー追加は非同期で実行される。

## パフォーマンス要件

- run()メソッドは30秒以内に完了することが推奨（CRON_THRESHOLD）
- 長時間かかる場合はSlowTriggerAdminMonitorで警告

## セキュリティ考慮事項

- タイマートリガー設定はジョブの設定権限を持つユーザーのみが変更可能
- ビルド実行自体はシステム権限で行われる

## 備考

- TimerTriggerはSCMTriggerと異なり、SCMの変更チェックを行わない
- シンプルな構造で、主にrun()メソッドでビルドをスケジュールするのみ

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

TimerTriggerの構造は非常にシンプルで、親クラスTriggerから継承したspecフィールドのみを使用する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | TimerTrigger.java | `core/src/main/java/hudson/triggers/TimerTrigger.java` | クラス定義、コンストラクタ |
| 1-2 | Trigger.java | `core/src/main/java/hudson/triggers/Trigger.java` | spec、tabsフィールド |

**読解のコツ**: TimerTriggerは非常にシンプルなクラスで、Triggerを継承してrun()メソッドのみを実装している。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | TimerTrigger.java | `core/src/main/java/hudson/triggers/TimerTrigger.java` | run()メソッド |

**主要処理フロー**:
- **58-68行目**: run()メソッド - ビルドスケジュール処理
- **60-64行目**: プロジェクトの取得とnullチェック
- **66行目**: scheduleBuild(0, new TimerTriggerCause())呼び出し

#### Step 3: Causeクラスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | TimerTrigger.java | `core/src/main/java/hudson/triggers/TimerTrigger.java` | TimerTriggerCause内部クラス |

**主要処理フロー**:
- **70-82行目**: TimerTriggerCause - ビルド原因を表すクラス
- **78行目**: getShortDescription() - ビルド履歴に表示される説明文

#### Step 4: Descriptorを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | TimerTrigger.java | `core/src/main/java/hudson/triggers/TimerTrigger.java` | DescriptorImpl |

**主要処理フロー**:
- **84-94行目**: DescriptorImpl - UI表示名とisApplicable()

### プログラム呼び出し階層図

```
Cron.doRun() [毎分実行]
    │
    └─ Trigger.checkTriggers(Calendar)
           │
           ├─ TimerTrigger.tabs.check(Calendar)
           │      └─ cronスケジュール判定
           │
           └─ [マッチした場合]
                  │
                  └─ TimerTrigger.run()
                         │
                         ├─ Trigger.job取得
                         │
                         └─ project.scheduleBuild(0, TimerTriggerCause)
                                │
                                └─ ビルドキュー追加
```

### データフロー図

```
[入力]                    [処理]                         [出力]

cronスケジュール     TimerTrigger
(spec)          ├─ CronTabList.check() ───▶   スケジュール判定
                │
ジョブ設定      └─ run()
(Trigger.job)      ├─ scheduleBuild() ─────▶   ビルドキュー追加
                   └─ TimerTriggerCause ────▶   ビルド原因記録
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| TimerTrigger.java | `core/src/main/java/hudson/triggers/TimerTrigger.java` | ソース | タイマートリガーの実装クラス |
| Trigger.java | `core/src/main/java/hudson/triggers/Trigger.java` | ソース | トリガーの抽象基底クラス |
| TriggerDescriptor.java | `core/src/main/java/hudson/triggers/TriggerDescriptor.java` | ソース | トリガーDescriptor基底クラス |
| CronTabList.java | `core/src/main/java/hudson/scheduler/CronTabList.java` | ソース | cronスケジュール解析 |
| Hash.java | `core/src/main/java/hudson/scheduler/Hash.java` | ソース | H構文のハッシュ計算 |
| Cause.java | `core/src/main/java/hudson/model/Cause.java` | ソース | ビルド原因の基底クラス |
