Skip to content

Instantly share code, notes, and snippets.

@Elschnagoo
Created July 28, 2022 02:37
Show Gist options
  • Save Elschnagoo/182949cffd7a646c3aa65941312c29c4 to your computer and use it in GitHub Desktop.
Save Elschnagoo/182949cffd7a646c3aa65941312c29c4 to your computer and use it in GitHub Desktop.
Simple Typescript Semaphor / Mutex
import crypto from 'crypto';
export type SemElement = [string, (value: any | PromiseLike<any>) => void];
export class Semaphor {
private curQueue: Map<string, SemElement>;
private readonly max: number;
private callbackQueue: SemElement[];
constructor(max = 1) {
this.curQueue = new Map();
this.callbackQueue = [];
this.max = max;
this.release = this.release.bind(this);
}
private hasFree() {
return this.curQueue.size < this.max;
}
async request(): Promise<() => void> {
const uuid = crypto.randomUUID();
return new Promise((resolve) => {
this.callbackQueue.push([uuid, resolve]);
this.startNext();
});
}
private startNext() {
if (this.hasFree()) {
const el = this.callbackQueue.shift();
if (el) {
const [uuid, resolve] = el;
this.curQueue.set(uuid, el);
resolve(() => {
this.release(uuid);
});
this.startNext();
}
}
}
private release(uuid: string) {
if (this.curQueue.has(uuid)) {
this.curQueue.delete(uuid);
}
this.startNext();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment