@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.
112 lines (106 loc) • 3.44 kB
JavaScript
/**
* @module Lock
*/
/**
* To utilize the `RedisLockAdapter`, you must install the `"ioredis"` package.
*
* Note in order to use `RedisLockAdapter` correctly, ensure you use a single, consistent database across all server instances.
*
* IMPORT_PATH: `"@daiso-tech/core/lock/adapters"`
* @group Adapters
*/
export class RedisLockAdapter {
database;
/**
* @example
* ```ts
* import { RedisLockAdapter } from "@daiso-tech/core/lock/adapters";
* import Redis from "ioredis";
*
* const database = new Redis("YOUR_REDIS_CONNECTION_STRING");
* const lockAdapter = new RedisLockAdapter(database);
* ```
*/
constructor(database) {
this.database = database;
this.initAquireCommand();
this.initReleaseCommand();
this.initRefreshComand();
}
initAquireCommand() {
if (typeof this.database.daiso_lock_acquire === "function") {
return;
}
this.database.defineCommand("daiso_lock_acquire", {
numberOfKeys: 1,
lua: `
local key = KEYS[1];
local owner = ARGV[1];
local ttl = ARGV[2]
local hasKey = redis.call("exists", key)
if hasKey == 1 then
return 0
end
if ttl == "null" then
redis.call("set", key, owner, "nx")
else
redis.call("set", key, owner, "px", ttl, "nx")
end
return 1
`,
});
}
initReleaseCommand() {
if (typeof this.database.daiso_lock_release === "function") {
return;
}
this.database.defineCommand("daiso_lock_release", {
numberOfKeys: 1,
lua: `
local key = KEYS[1];
local owner = ARGV[1];
local owner_ = redis.call("get", key)
if owner_ == owner then
redis.call("del", key)
return 1
end
return 0
`,
});
}
initRefreshComand() {
if (typeof this.database.daiso_lock_refresh === "function") {
return;
}
this.database.defineCommand("daiso_lock_refresh", {
numberOfKeys: 1,
lua: `
local key = KEYS[1];
local owner = ARGV[1];
local ttl = ARGV[2]
local owner_ = redis.call("get", key)
if owner_ == owner then
redis.call("pexpire", key, ttl)
return 1
end
return 0
`,
});
}
async acquire(key, owner, ttl) {
const result = await this.database.daiso_lock_acquire(key, owner, String(ttl?.toMilliseconds() ?? null));
return result > 0;
}
async release(key, owner) {
const result = await this.database.daiso_lock_release(key, owner);
return result === 1;
}
async forceRelease(key) {
await this.database.del(key);
}
async refresh(key, owner, ttl) {
const result = await this.database.daiso_lock_refresh(key, owner, ttl.toMilliseconds().toString());
return Boolean(result);
}
}
//# sourceMappingURL=redis-lock-adapter.js.map