2022-02-09 21:21:17 +01:00
|
|
|
export default class Mutex {
|
2024-07-25 00:12:24 +03:00
|
|
|
private current: Promise<void>;
|
|
|
|
|
2022-02-09 21:21:17 +01:00
|
|
|
constructor() {
|
|
|
|
this.current = Promise.resolve();
|
|
|
|
}
|
|
|
|
|
|
|
|
lock() {
|
2024-07-25 00:12:24 +03:00
|
|
|
let resolveFun: () => void;
|
2025-01-09 18:07:02 +02:00
|
|
|
const subPromise = new Promise<void>((resolve) => (resolveFun = () => resolve()));
|
2022-02-09 21:21:17 +01:00
|
|
|
// Caller gets a promise that resolves when the current outstanding lock resolves
|
|
|
|
const newPromise = this.current.then(() => resolveFun);
|
|
|
|
// Don't allow the next request until the new promise is done
|
|
|
|
this.current = subPromise;
|
|
|
|
// Return the new promise
|
|
|
|
return newPromise;
|
2025-01-09 18:07:02 +02:00
|
|
|
}
|
2022-02-09 21:21:17 +01:00
|
|
|
|
2025-03-03 23:34:54 +02:00
|
|
|
async runExclusively(cb: () => Promise<void>) {
|
2022-02-09 21:21:17 +01:00
|
|
|
const unlock = await this.lock();
|
|
|
|
|
|
|
|
try {
|
2022-06-29 22:38:35 +02:00
|
|
|
return await cb();
|
2025-01-09 18:07:02 +02:00
|
|
|
} finally {
|
2022-02-09 21:21:17 +01:00
|
|
|
unlock();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|