🐣
[capnp][kj]タイムアウト処理
注意 : 今回作成した timeoutSafe は終了しないタスクはタイムアウトできないので注意.
概要
レスポンスを待つ場合に処理をタイムアウトさせたい場合がある.
その時 kj::Timer::afterDelay() を使って規定時間経過後処理を止めることができた.
サンプルソースコード
結論
以下の様な形でタイムアウトを設定させたい task を渡して上げて, timer とタイムアウト時間を指定する.
kj::Promise<bool> timeoutSafe(kj::Promise<void>&& task, kj::Timer& timer,
kj::Duration timeout) {
auto timeoutPromise = timer.afterDelay(timeout).then([]() {
LOG_COUT << "[ReusableTask] Timeout : Task timed out.\n";
return false;
});
return kj::mv(task)
.then([]() {
LOG_COUT << "[ReusableTask] Timeout : Task completed successfully.\n";
return true;
})
.exclusiveJoin(kj::mv(timeoutPromise));
}
ソースコード解説
以下の部分でタイムアウト用のタイマーを作成している.
今回は, タイムアウト完了したというメッセージを表示.
これは普通のタイマーの使い方と同じ.
auto timeoutPromise = timer.afterDelay(timeout).then([]() {
LOG_COUT << "[ReusableTask] Timeout : Task timed out.\n";
return false;
});
return 部分がタイムアウトさせるための処理.
2つのタスクが存在する.
- task : 処理に時間がかかるタスク.
- timeoutPromise : タイムアウト時間を計測するタスク
この task, timeoutPromise のどちらかが先に完了した時点での結果を返す.
これによってタイムアウトを実現することができる.
exclusiveJoin 使用せずに wait でも似たような動作になったが
その場合タイムアウトしたときに例外が送出されてしまった.
return kj::mv(task)
.then([]() {
LOG_COUT << "[ReusableTask] Timeout : Task completed successfully.\n";
return true;
})
.exclusiveJoin(kj::mv(timeoutPromise));
最後に
exclusiveJoin を使用して3つ以上のタスクを待てるかどうかは確認できていない.
Discussion