汎用ユーティリティー
Asyncmux クラスと AsyncmuxLock の API をまとめます。lock・rLock のシグネチャー、ロックオプション、解放のルールを説明します。
Asyncmux クラス
キーごとに独立したロックと、すべてのロックと競合するグローバルロックを管理します。
import { Asyncmux } from "asyncmux";
const mux = new Asyncmux();
constructor()
constructor(options?: AsyncmuxOptions);
インスタンスのオプションを指定して初期化します。インスタンスごとに独立したロック状態を持ちます。
lock()
lock(): Promise<AsyncmuxLock>;
キーなしの書き込みロック(グローバル書き込みロック)を取得します。インスタンス内のすべてのロックと競合します。
lock(key)
lock(key: string): Promise<AsyncmuxLock>;
指定したキーの書き込みロックを取得します。同じキーのロックとは競合し、異なるキーのロックとは共存できます。
lock(options)
lock(options: AsyncmuxLockOptions): Promise<AsyncmuxLock>;
オプションでキーと AbortSignal を指定して、書き込みロックを取得します。key を省略した場合はグローバル書き込みロックになります。
using _ = await mux.lock({ key: "user:42", signal: controller.signal });
rLock()
rLock(): Promise<AsyncmuxLock>;
キーなしの読み取りロック(グローバル読み取りロック)を取得します。すべての書き込みロックと競合し、読み取りロックとは共存できます。
rLock(key)
rLock(key: string): Promise<AsyncmuxLock>;
指定したキーの読み取りロックを取得します。同じキーの書き込みロックとは競合し、読み取りロック同士は共存できます。
rLock(options)
rLock(options: AsyncmuxLockOptions): Promise<AsyncmuxLock>;
オプションでキーと AbortSignal を指定して、読み取りロックを取得します。key を省略した場合はグローバル読み取りロックになります。
共通の挙動
lock と rLock はすべて AsyncmuxLock で解決される Promise を返します。
- 競合するロックが保持されている間は待機します。待機中の要求は到着順に処理されます。
signalが中断された場合、要求はキューから削除され、signal.reasonで拒否されます。- 既定では再入を検出しません。同じキーのロックを保持したまま再度取得すると、デッドロックします。
preventReentrancyを有効にするとReentrantLockErrorを投げます。
競合の詳細はキー付きロックを参照してください。
AsyncmuxOptions
Asyncmux クラスのコンストラクターに渡すオプションです。
preventReentrancy?boolean
再入を禁止するかどうかです。`true` の場合、同じ非同期コンテキストで保持中のロックと競合する要求に対して同期的に `ReentrantLockError` を投げます。`node:async_hooks` の `AsyncLocalStorage` を利用できない環境では無視されます。
booleanAsyncmuxLockOptions
lock と rLock のオプションです。
key?string
ロック対象のキーです。省略するとグローバルロックになります。
stringsignal?AbortSignal
ロック待機を中断するためのシグナルです。
AbortSignalAsyncmuxLock クラス
取得したロックを表します。インスタンスは各 API の戻り値としてのみ得られ、コンストラクターは内部用です。
released
ロックが解放済みかどうかを返します。
get released(): boolean;
release()
ロックを解放します。同じロックに対して 2 回呼び出すと LockReleasedError が投げられます。解放処理が例外を投げた場合でも、ロックは解放済みとして扱われます。
release(): void;
[Symbol.dispose]()
using 構文による自動解放を実装します。解放済みの場合は何も行いません。
[Symbol.dispose](): void;
{
using _ = await mux.lock("key");
// スコープを抜けると release() が呼ばれます。
}