# 通知設計書 6-GlobalOperationStarted

## 概要

本ドキュメントは、Roslynプロジェクトにおける`GlobalOperationStarted`イベント通知の設計仕様を記載するものである。このイベントは、ビルドなどのグローバル操作（ホスト全体に影響を及ぼす重い処理）が開始された際に発火するイベント通知であり、バックグラウンド処理の一時停止やリソース使用量の調整に活用される。

### 本通知の処理概要

`GlobalOperationStarted`は、`IGlobalOperationNotificationService`インターフェースで定義された`Started`イベントであり、グローバル操作の開始時にサブスクライバへ通知を送信する。グローバル操作とは、ビルド、デバッグ開始、Gitブランチ切り替え（BulkFileOperation）など、ホスト環境全体に影響を与える処理を指す。

**業務上の目的・背景**：Visual Studioなどの開発環境では、ビルドやデバッグなどの重い処理が実行される際、バックグラウンドで動作している分析処理やソリューションクローラーがCPUやメモリリソースを消費し、メイン操作のパフォーマンスに影響を与える可能性がある。このイベント通知により、バックグラウンド処理を一時停止し、メイン操作に優先的にリソースを割り当てることで、ユーザー体験を向上させる。操作完了後は`Stopped`イベントでバックグラウンド処理を再開する。

**通知の送信タイミング**：`IGlobalOperationNotificationService.Start()`メソッドが呼び出され、最初のグローバル操作が開始された時点で発火する。複数の操作が同時に開始されている場合、最初の操作開始時のみイベントが発火する（参照カウント方式）。

**通知の受信者**：`Started`イベントをサブスクライブしているコンポーネント。具体的には、SolutionCrawler、プリエンプティブなリモートホスト同期、その他のバックグラウンドアイドルプロセッサなど。

**通知内容の概要**：`EventArgs.Empty`が送信される。通知自体には詳細な情報は含まれず、「グローバル操作が開始された」というシグナルのみを伝達する。

**期待されるアクション**：イベントをサブスクライブしているコンポーネントは、バックグラウンド処理を一時停止し、グローバル操作に対してリソースを譲渡する。

## 通知種別

アプリ内イベント通知（EventHandler）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期イベント発火（AsyncBatchingWorkQueueで遅延処理） |
| 優先度 | 高（リソース調整のため即時通知が重要） |
| リトライ | 無し（イベント通知のため） |

### 送信先決定ロジック

`Started`イベントにサブスクライブしているすべてのハンドラに対してイベントが発火される。サブスクライバの登録・解除はイベントの標準的な`+=`/`-=`演算子で行う。

## 通知テンプレート

### イベント定義

```csharp
public event EventHandler Started;
```

### イベント引数

| 項目 | 内容 |
|-----|------|
| sender | IGlobalOperationNotificationServiceインスタンス |
| args | EventArgs.Empty |

### 添付ファイル

| ファイル名 | 形式 | 条件 | 説明 |
|----------|------|------|------|
| N/A | - | - | イベント通知のため添付ファイルなし |

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| N/A | - | イベント引数はEventArgs.Empty | - |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| システム処理 | IGlobalOperationNotificationService.Start()呼び出し | 最初の操作開始時 | グローバル操作開始メソッドの呼び出し |
| システム処理 | BulkFileOperation.Begin | Begin イベント発火時 | Gitブランチ切り替え等のファイル一括操作開始 |
| システム処理 | ビルド開始 | ビルドプロセス開始時 | ソリューション/プロジェクトのビルド開始 |
| システム処理 | ソリューション変更イベント | SolutionEventMonitor検知時 | ソリューションの変更操作開始 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| 既に他のグローバル操作が実行中の場合 | 参照カウントが1以上の場合、追加のStartedイベントは発火しない |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[Start operation が呼び出される] --> B[ロックを取得]
    B --> C[GlobalOperationRegistrationを作成]
    C --> D[registrationsに追加]
    D --> E[operationsに操作名を追加]
    E --> F{registrations.Count == 1?}
    F -->|Yes| G[EventQueueにtrue Added]
    F -->|No| H[Registrationを返す]
    G --> I[ProcessEventsAsyncが実行]
    I --> J[Started イベントを発火]
    J --> H
```

## データベース参照・更新仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| N/A | - | データベースアクセスなし（インメモリ管理） |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| N/A | - | データベースへの更新なし |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| イベントハンドラ例外 | サブスクライバが例外をスローした場合 | 例外はキャッチされず伝播する可能性あり |
| シャットダウン中 | 環境シャットダウン中にイベント発火 | ファイナライザでの検証をスキップ |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0（リトライなし） |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし（グローバル操作の頻度に依存） |
| 1日あたり上限 | 制限なし |

### 配信時間帯

グローバル操作の開始に応じて即座に発火されるため、時間帯制限なし。

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

- イベントハンドラは信頼されたコード内でのみサブスクライブされる
- イベント引数には機密情報は含まれない（EventArgs.Empty）
- イベントハンドラの実行は同期的であり、長時間実行するハンドラはパフォーマンスに影響する可能性がある

## 備考

- `AbstractGlobalOperationNotificationService`が抽象基底クラスとして実装を提供
- `VisualStudioGlobalOperationNotificationService`がVisual Studio環境での具体実装
- 参照カウント方式により、ネストされたグローバル操作を適切に管理
- `AsyncBatchingWorkQueue`を使用してイベント発火を最適化
- `GlobalOperationRegistration`はIDisposableを実装し、Disposeで操作終了を通知

---

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

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

### 推奨読解順序

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

まず、インターフェース定義とイベントの構造を理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | IGlobalOperationNotificationService.cs | `src/Features/Core/Portable/ExternalAccess/UnitTesting/Notification/IGlobalOperationNotificationService.cs` | インターフェース定義、Startedイベント（行17-18）とStartメソッド（行28）を理解する |

**読解のコツ**: `Started`と`Stopped`の2つのイベントがペアになっていること、`Start`メソッドがIDisposableを返すことに注目。

#### Step 2: 抽象基底クラスを理解する

参照カウント方式の実装詳細を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AbstractGlobalOperationNotificationService.cs | `src/Features/Core/Portable/ExternalAccess/UnitTesting/Notification/AbstractGlobalOperationNotificationService.cs` | Startメソッドの実装（行59-79）、参照カウント管理、AsyncBatchingWorkQueueの使用を理解する |
| 2-2 | AbstractGlobalOperationNotificationService.GlobalOperationRegistration.cs | `src/Features/Core/Portable/ExternalAccess/UnitTesting/Notification/AbstractGlobalOperationNotificationService.GlobalOperationRegistration.cs` | Registrationクラスの実装（Disposeで操作終了を通知） |

**主要処理フロー**:
1. **行59-79（Start）**: ロックを取得し、Registrationを作成・登録
2. **行71-75**: registrations.Count == 1の場合のみEventQueueにtrueを追加
3. **行48-57（ProcessEventsAsync）**: キューから取り出してStarted/Stoppedイベントを発火

#### Step 3: Visual Studio実装を理解する

具体的な使用例とBulkFileOperation対応を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | VisualStudioGlobalOperationNotificationService.cs | `src/VisualStudio/Core/Def/ExternalAccess/UnitTesting/VisualStudioGlobalOperationNotificationService.cs` | BulkFileOperation.Begin/Endへのフック（行42-43）、SolutionEventMonitorとの連携を理解する |

#### Step 4: サブスクライバを理解する

イベントをサブスクライブしている箇所を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | UnitTestingGlobalOperationAwareIdleProcessor.cs | `src/Features/Core/Portable/ExternalAccess/UnitTesting/SolutionCrawler/UnitTestingGlobalOperationAwareIdleProcessor.cs` | グローバル操作認識アイドルプロセッサでのイベントサブスクライブ例 |

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

```
グローバル操作のトリガー（ビルド、BulkFileOperation等）
    │
    └─ IGlobalOperationNotificationService.Start(operation)
           │
           ├─ AbstractGlobalOperationNotificationService
           │      │
           │      ├─ lock(_gate) で排他制御
           │      │
           │      ├─ GlobalOperationRegistration作成
           │      │
           │      ├─ _registrations.Add(registration)
           │      │
           │      ├─ _operations.Add(operation)
           │      │
           │      └─ if (Count == 1) _eventQueue.AddWork(true)
           │             │
           │             └─ ProcessEventsAsync
           │                    │
           │                    └─ Started?.Invoke(this, EventArgs.Empty)
           │
           └─ IDisposable (GlobalOperationRegistration) を返す
                  │
                  └─ Dispose() → service.Done(this) → Stopped イベント
```

### データフロー図

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

operation: string ──────▶ Start(operation)
                                │
                                ▼
                         参照カウント確認
                                │
                                ▼
                      ┌─ Count == 1? ─┐
                      │               │
                     Yes             No
                      │               │
                      ▼               │
               EventQueue.AddWork(true)
                      │               │
                      ▼               │
               ProcessEventsAsync     │
                      │               │
                      ▼               │
               Started イベント発火 ──┴──▶ サブスクライバへ通知
                      │
                      ▼
               IDisposable返却 ──────▶ 呼び出し元（操作完了時にDispose）
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| IGlobalOperationNotificationService.cs | `src/Features/Core/Portable/ExternalAccess/UnitTesting/Notification/IGlobalOperationNotificationService.cs` | インターフェース | サービスの契約定義 |
| AbstractGlobalOperationNotificationService.cs | `src/Features/Core/Portable/ExternalAccess/UnitTesting/Notification/AbstractGlobalOperationNotificationService.cs` | ソース | 抽象基底クラス実装 |
| AbstractGlobalOperationNotificationService.GlobalOperationRegistration.cs | `src/Features/Core/Portable/ExternalAccess/UnitTesting/Notification/AbstractGlobalOperationNotificationService.GlobalOperationRegistration.cs` | ソース | 操作登録クラス |
| VisualStudioGlobalOperationNotificationService.cs | `src/VisualStudio/Core/Def/ExternalAccess/UnitTesting/VisualStudioGlobalOperationNotificationService.cs` | ソース | VS環境の具体実装 |
| SolutionEventMonitor.cs | `src/VisualStudio/Core/Def/ExternalAccess/UnitTesting/SolutionEventMonitor.cs` | ソース | ソリューションイベント監視 |
| UnitTestingGlobalOperationAwareIdleProcessor.cs | `src/Features/Core/Portable/ExternalAccess/UnitTesting/SolutionCrawler/UnitTestingGlobalOperationAwareIdleProcessor.cs` | ソース | サブスクライバ例 |
