中断
AbortSignal をロック要求に渡して、待機中のロック取得を中断する方法と、中断が起きるタイミングを説明します。
概要
関数 API と Asyncmux クラスには、ロック待機を中断するための AbortSignal を渡せます。デコレーター API には渡せません。
// 関数 API
using _ = await asyncmux(this, signal);
// Asyncmux クラス
using _ = await mux.lock({ key: "key", signal });
中断が起きるタイミング
- 呼び出し時にすでに中断されている場合、ロックは要求されず、
signal.reasonで即座に拒否されます。 - 待機中に中断されると、要求はキューから削除され、
signal.reasonで拒否されます。後続の要求はそのまま処理されます。 - ロックを取得した後に中断しても、取得済みのロックは解放されません。解放は
release()またはusingで行います。
import { Asyncmux } from "asyncmux";
const mux = new Asyncmux();
const controller = new AbortController();
const lockPromise = mux.lock({
key: "resource",
signal: controller.signal,
});
setTimeout(() => {
controller.abort(new Error("タイムアウトしました"));
}, 1000);
const lock = await lockPromise.catch((error) => {
// 中断された場合は signal.reason がそのまま渡されます。
console.error(error);
return null;
});
if (lock) {
try {
// ロックを取得して実行します。
} finally {
lock.release();
}
}
中断理由
AbortController.abort() に渡した値が signal.reason になります。引数を省略した場合は、実行環境の AbortError(DOMException)が理由になります。
const controller = new AbortController();
controller.abort("中断理由");
await asyncmux(target, controller.signal); // "中断理由" で拒否します。