@daiso-tech/core
Version:
The library offers flexible, framework-agnostic solutions for modern web applications, built on adaptable components that integrate seamlessly with popular frameworks like Next Js.
144 lines • 4.19 kB
JavaScript
/**
* @module Lock
*/
import {} from "../../../../lock/contracts/_module.js";
import {} from "../../../../time-span/implementations/_module.js";
import {} from "../../../../utilities/_module.js";
/**
* Note the `MemoryLockAdapter` is limited to single process usage and cannot be shared across multiple servers or different processes.
* This adapter is meant for testing.
*
* IMPORT_PATH: `"@daiso-tech/core/lock/memory-lock-adapter"`
* @group Adapters
*/
export class MemoryLockAdapter {
map;
/**
* @example
* ```ts
* import { MemoryLockAdapter } from "@daiso-tech/core/lock/memory-lock-adapter";
*
* const lockAdapter = new MemoryLockAdapter();
* ```
* You can also provide an `Map`.
* @example
* ```ts
* import { MemoryLockAdapter } from "@daiso-tech/core/lock/memory-lock-adapter";
*
* const map = new Map<any, any>();
* const lockAdapter = new MemoryLockAdapter(map);
* ```
*/
constructor(map = new Map()) {
this.map = map;
}
/**
* Removes all in-memory lock data.
*/
// eslint-disable-next-line @typescript-eslint/require-await
async deInit() {
for (const [key, lockData] of this.map) {
if (lockData.hasExpiration) {
clearTimeout(lockData.timeoutId);
}
this.map.delete(key);
}
}
// eslint-disable-next-line @typescript-eslint/require-await
async acquire(key, lockId, ttl) {
let lock = this.map.get(key);
if (lock !== undefined) {
return lock.owner === lockId;
}
if (ttl === null) {
lock = {
owner: lockId,
hasExpiration: false,
};
this.map.set(key, lock);
}
else {
const timeoutId = setTimeout(() => {
this.map.delete(key);
}, ttl.toMilliseconds());
lock = {
owner: lockId,
hasExpiration: true,
timeoutId,
expiration: ttl.toEndDate(),
};
this.map.set(key, lock);
}
return true;
}
// eslint-disable-next-line @typescript-eslint/require-await
async release(key, lockId) {
const lock = this.map.get(key);
if (lock === undefined) {
return false;
}
if (lock.owner !== lockId) {
return false;
}
if (lock.hasExpiration) {
clearTimeout(lock.timeoutId);
}
this.map.delete(key);
return true;
}
// eslint-disable-next-line @typescript-eslint/require-await
async forceRelease(key) {
const lock = this.map.get(key);
if (lock === undefined) {
return false;
}
if (lock.hasExpiration) {
clearTimeout(lock.timeoutId);
}
this.map.delete(key);
return true;
}
// eslint-disable-next-line @typescript-eslint/require-await
async refresh(key, lockId, ttl) {
const lock = this.map.get(key);
if (lock === undefined) {
return false;
}
if (lock.owner !== lockId) {
return false;
}
if (!lock.hasExpiration) {
return false;
}
clearTimeout(lock.timeoutId);
const timeoutId = setTimeout(() => {
this.map.delete(key);
}, ttl.toMilliseconds());
this.map.set(key, {
...lock,
timeoutId,
});
return true;
}
// eslint-disable-next-line @typescript-eslint/require-await
async getState(key) {
const lockData = this.map.get(key);
if (lockData === undefined) {
return null;
}
if (!lockData.hasExpiration) {
return {
owner: lockData.owner,
expiration: null,
};
}
if (lockData.expiration <= new Date()) {
return null;
}
return {
owner: lockData.owner,
expiration: lockData.expiration,
};
}
}
//# sourceMappingURL=memory-lock-adapter.js.map