
Proactorパターンとは、非同期処理を前提としたイベント駆動パターンです、
Reactorが「イベントの準備完了を待つ」のに対し、Proactorは「非同期処理の完了を待つ」。
非同期I/O操作(例:ファイル読み込み・ネットワーク通信)に特化しています。
OSやランタイムに「実行を委譲」し、完了時にコールバックを受け取る時などに使うようですね。
処理フロー
1. 非同期操作を開始する (I/Oリクエスト送信)
↓
2. OSやランタイムがバックグラウンドで処理
↓
3. 完了時にCompletionHandlerを呼び出す
↓
4. Handlerが結果を受け取って処理を続行
Reactorとの違い
| 比較項目 |
Reactor |
Proactor |
| 対応方式 |
同期的(I/O準備完了) |
| 非同期的(I/O完了) |
| 実行主体 |
アプリ側で読み書きを実行 |
OS/ランタイムが実行 |
| 主な利用例 |
select/poll/epoll ベース |
async/await, overlapped I/O |
| JSの例 |
addEventListenerでイベントを待つ |
fetch, async/await, Promise |
JavaScript的な理解
JavaScriptのPromise / async/awaitモデルは、まさにProactorパターンに近い。
Node.jsのlibuv(Cレイヤー)は、内部的にProactor的モデル(非同期I/O完了通知)を採用している。
簡易サンプルコード(Proactor的処理)
// Proactorパターン風の非同期I/O処理
function asyncReadFile(path, completionHandler) {
// OS(Node.js)に非同期I/Oを依頼
require('fs').readFile(path, 'utf8', (err, data) => {
// I/O完了後、CompletionHandlerを呼び出す
completionHandler(err, data);
});
}
// CompletionHandler(完了時に実行される)
function onReadComplete(err, data) {
if (err) {
console.error('Read failed:', err);
} else {
console.log('File contents:', data);
}
}
// 非同期I/Oを開始
asyncReadFile('./sample.txt', onReadComplete);
console.log('I/O request sent, continuing other work...');
ポイント
・readFile は非同期でOSに委譲される。
・JS側は「I/O完了イベント」を待つだけ。
・これはまさにProactorの典型構造。
擬似的な流れ
App OS
│ asyncReadFile │
│ ---> │ 実際のI/Oを開始
│ │
│ │ (I/O完了)
│ <---- │ CompletionHandler呼び出し
│ onReadComplete │
あとがき
Proactorパターンは、Javasxriptでは少し古い書き方のようで、最近では、async~awaitで書いた方がコードがスッキリすると言われています。
ただ、古い書き方を知っておくことで、設計の安定感にもつながるので、こうしたイベント発火制御するReactor、発火後の挙動を制御するProactorを理解しておくことは重要ですよね。
0 件のコメント:
コメントを投稿