Async Reader-Writer Lock
Coordinate concurrent async readers and exclusive writers with a fair, promise-based reader-writer lock.
Code
export class AsyncReaderWriterLock {
private readers = 0;
private writer = false;
private queue: Array<{ write: boolean; resolve: () => void }> = [];
async acquireRead(): Promise<() => void> {
await this.request(false);
this.readers += 1;
return () => this.release(false);
}
async acquireWrite(): Promise<() => void> {
await this.request(true);
this.writer = true;
return () => this.release(true);
}
private request(write: boolean): Promise<void> {
if (this.queue.length === 0 && !this.writer && (write || this.readers >= 0)) {
if (write ? this.readers === 0 : !this.writer) return Promise.resolve();
}
return new Promise((resolve) => this.queue.push({ write, resolve }));
}
private release(write: boolean) {
if (write) this.writer = false;
else this.readers -= 1;
this.drain();
}
private drain() {
while (this.queue.length > 0) {
const next = this.queue[0] as { write: boolean; resolve: () => void };
if (next.write) {
if (this.writer || this.readers > 0) return;
(this.queue.shift() as { resolve: () => void }).resolve();
return;
}
(this.queue.shift() as { resolve: () => void }).resolve();
}
}
}Report a problem with this exampleOpens a pre-filled issue on GitHub.