UNPKG

@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.

134 lines (122 loc) 4.41 kB
/** * @module Lock */ import { LOCK_REFRESH_RESULT, } from "../../../../lock/contracts/_module-exports.js"; /** * To utilize the `RedisLockAdapter`, you must install the [`"ioredis"`](https://www.npmjs.com/package/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 expiration = tonumber(ARGV[2]) if redis.call("exists", key) == 1 then return 0 end if expiration == nil then redis.call("set", key, owner, "nx") else redis.call("set", key, owner, "px", expiration, "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]; if redis.call("exists", key) == 0 then return 0 end local isNotCurrentOwner = redis.call("get", key) ~= owner if isNotCurrentOwner then return 0 end redis.call("del", key) return 1 `, }); } initRefreshComand() { if (typeof this.database.daiso_lock_refresh === "function") { return; } this.database.defineCommand("daiso_lock_refresh", { numberOfKeys: 1, lua: ` -- Arguments local key = KEYS[1]; local owner = ARGV[1]; local expiration = ARGV[2] -- Constant values local REFRESHED = ARGV[3] local UNOWNED_REFRESH = ARGV[4] local UNEXPIRABLE_KEY = ARGV[5] if redis.call("exists", key) == 0 then return UNOWNED_REFRESH end local isNotCurrentOwner = redis.call("get", key) ~= owner if redis.call("get", key) ~= owner then return UNOWNED_REFRESH end local currentExpiration = redis.call("pttl", key) local isUnexpireable = currentExpiration == -1 if isUnexpireable then return UNEXPIRABLE_KEY end redis.call("pexpire", key, expiration) return REFRESHED `, }); } async acquire(key, owner, ttl) { const result = await this.database.daiso_lock_acquire(key, owner, String(ttl?.toMilliseconds() ?? null)); return result === 1; } async release(key, owner) { const result = await this.database.daiso_lock_release(key, owner); return result === 1; } async forceRelease(key) { const result = await this.database.del(key); return result > 0; } async refresh(key, owner, ttl) { return await this.database.daiso_lock_refresh(key, owner, ttl.toMilliseconds().toString(), LOCK_REFRESH_RESULT.REFRESHED, LOCK_REFRESH_RESULT.UNOWNED_REFRESH, LOCK_REFRESH_RESULT.UNEXPIRABLE_KEY); } } //# sourceMappingURL=redis-lock-adapter.js.map