Skip to content

Commit 6a121e3

Browse files
committed
feat: add RAMLock to utils
1 parent d6f5292 commit 6a121e3

File tree

2 files changed

+34
-3
lines changed

2 files changed

+34
-3
lines changed

adminforth/index.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import SQLiteConnector from './dataConnectors/sqlite.js';
66
import CodeInjector from './modules/codeInjector.js';
77
import ExpressServer from './servers/express.js';
88
// import FastifyServer from './servers/fastify.js';
9-
import { ADMINFORTH_VERSION, listify, suggestIfTypo, RateLimiter, getClientIp } from './modules/utils.js';
9+
import { ADMINFORTH_VERSION, listify, suggestIfTypo, RateLimiter, RAMLock, getClientIp } from './modules/utils.js';
1010

1111
import {
1212
type AdminForthConfig,
@@ -42,7 +42,7 @@ export * from './types/Common.js';
4242
export * from './types/Adapters.js';
4343
export { interpretResource };
4444
export { AdminForthPlugin };
45-
export { suggestIfTypo, RateLimiter, getClientIp };
45+
export { suggestIfTypo, RateLimiter, RAMLock, getClientIp };
4646

4747

4848
class AdminForth implements IAdminForth {
@@ -478,7 +478,6 @@ class AdminForth implements IAdminForth {
478478
{ resource, recordId, record, oldRecord, adminUser, extra }:
479479
{ resource: AdminForthResource, recordId: any, record: any, oldRecord: any, adminUser: AdminUser, extra?: HttpExtra }
480480
): Promise<{ error?: string }> {
481-
482481
const err = this.validateRecordValues(resource, record);
483482
if (err) {
484483
return { error: err };

adminforth/modules/utils.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,4 +455,36 @@ export class RateLimiter {
455455
}
456456
}
457457

458+
}
459+
460+
export class RAMLock {
461+
private locks: Map<string, { locked: boolean; queue: Function[] }>;
462+
463+
constructor() {
464+
this.locks = new Map();
465+
}
466+
467+
_getLock(key) {
468+
if (!this.locks.has(key)) {
469+
this.locks.set(key, { locked: false, queue: [] });
470+
}
471+
return this.locks.get(key);
472+
}
473+
474+
async run(key, fn) {
475+
const lock = this._getLock(key);
476+
while (lock.locked) {
477+
await new Promise(resolve => lock.queue.push(resolve));
478+
}
479+
lock.locked = true;
480+
try {
481+
return await fn();
482+
} finally {
483+
lock.locked = false;
484+
if (lock.queue.length > 0) {
485+
const next = lock.queue.shift();
486+
next();
487+
}
488+
}
489+
}
458490
}

0 commit comments

Comments
 (0)