fix(acme): Fix port 80 ACME management and challenge route concurrency issues by deduplicating port listeners, preserving challenge route state across certificate manager recreations, and adding mutex locks to route updates.
This commit is contained in:
45
ts/proxies/smart-proxy/utils/mutex.ts
Normal file
45
ts/proxies/smart-proxy/utils/mutex.ts
Normal file
@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Simple mutex implementation for async operations
|
||||
*/
|
||||
export class Mutex {
|
||||
private isLocked: boolean = false;
|
||||
private waitQueue: Array<() => void> = [];
|
||||
|
||||
/**
|
||||
* Acquire the lock
|
||||
*/
|
||||
async acquire(): Promise<void> {
|
||||
return new Promise<void>((resolve) => {
|
||||
if (!this.isLocked) {
|
||||
this.isLocked = true;
|
||||
resolve();
|
||||
} else {
|
||||
this.waitQueue.push(resolve);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Release the lock
|
||||
*/
|
||||
release(): void {
|
||||
this.isLocked = false;
|
||||
const nextResolve = this.waitQueue.shift();
|
||||
if (nextResolve) {
|
||||
this.isLocked = true;
|
||||
nextResolve();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run a function exclusively with the lock
|
||||
*/
|
||||
async runExclusive<T>(fn: () => Promise<T>): Promise<T> {
|
||||
await this.acquire();
|
||||
try {
|
||||
return await fn();
|
||||
} finally {
|
||||
this.release();
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user