Aborting
How to pass an AbortSignal to a lock request to abort a pending acquisition, and when aborts take effect.
Overview
The function API and the Asyncmux class accept an AbortSignal to abort a lock wait. The decorator API does not.
// Function API
using _ = await asyncmux(this, signal);
// Asyncmux class
using _ = await mux.lock({ key: "key", signal });
When aborts take effect
- When the signal is already aborted at call time, the lock is never requested and the call rejects immediately with
signal.reason. - When aborted while waiting, the request is removed from the queue and rejects with
signal.reason. Subsequent requests continue to be processed. - Aborting after the lock has been acquired does not release it. Release it with
release()orusing.
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("Timed out"));
}, 1000);
const lock = await lockPromise.catch((error) => {
// On abort, signal.reason is passed through as-is.
console.error(error);
return null;
});
if (lock) {
try {
// Run with the lock acquired.
} finally {
lock.release();
}
}
Abort reason
The value passed to AbortController.abort() becomes signal.reason. When omitted, the runtime’s AbortError (DOMException) is used as the reason.
const controller = new AbortController();
controller.abort("Abort reason");
await asyncmux(target, controller.signal); // Rejects with "Abort reason".