UNPKG

@solid/community-server

Version:

Community Solid Server: an open and modular implementation of the Solid specifications

108 lines (105 loc) 3.67 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.REDIS_LUA_SCRIPTS = void 0; exports.fromResp2ToBool = fromResp2ToBool; const InternalServerError_1 = require("../../errors/InternalServerError"); const SUFFIX_WLOCK = '.wlock'; const SUFFIX_LOCK = '.lock'; const SUFFIX_COUNT = '.count'; const LOCKED = 'locked'; /** * Lua scripts to be used as Redis operations. */ exports.REDIS_LUA_SCRIPTS = { acquireReadLock: ` -- Return 0 if an entry already exists. local lockKey = KEYS[1].."${SUFFIX_WLOCK}" if redis.call("exists", lockKey) == 1 then return 0 end -- Return true if succeeded (and counter is incremented) local countKey = KEYS[1].."${SUFFIX_COUNT}" return redis.call("incr", countKey) > 0 `, acquireWriteLock: ` -- Return 0 if a lock entry already exists or read count is > 0 local lockKey = KEYS[1].."${SUFFIX_WLOCK}" local countKey = KEYS[1].."${SUFFIX_COUNT}" local count = tonumber(redis.call("get", countKey)) if ((redis.call("exists", lockKey) == 1) or (count ~= nil and count > 0)) then return 0 end -- Set lock and respond with 'OK' if succeeded (otherwise null) return redis.call("set", lockKey, "${LOCKED}"); `, releaseReadLock: ` -- Return 1 after decreasing the counter, if counter is < 0 now: return '-ERR' local countKey = KEYS[1].."${SUFFIX_COUNT}" local result = redis.call("decr", countKey) if result >= 0 then return 1 else return redis.error_reply("Error trying to release readlock when read count was 0.") end `, releaseWriteLock: ` -- Release the lock and reply with 1 if succeeded (otherwise return '-ERR') local lockKey = KEYS[1].."${SUFFIX_WLOCK}" local result = redis.call("del", lockKey) if (result > 0) then return 1 else return redis.error_reply("Error trying to release writelock that did not exist.") end `, acquireLock: ` -- Return 0 if lock entry already exists, or 'OK' if it succeeds in setting the lock entry. local key = KEYS[1].."${SUFFIX_LOCK}" if redis.call("exists", key) == 1 then return 0 end -- Return 'OK' if succeeded setting entry return redis.call("set", key, "${LOCKED}"); `, releaseLock: ` -- Release the lock and reply with 1 if succeeded (otherwise return '-ERR') local key = KEYS[1].."${SUFFIX_LOCK}" local result = redis.call("del", key) if result > 0 then return 1 else return redis.error_reply("Error trying to release lock that did not exist.") end `, }; /** * Convert a RESP2 response to a boolean. * * @param result - The Promise-wrapped result of a RESP2 Redis function. * * @returns * `1`, `'OK'`: return `true` * * `0`: returns `false` * * `-ERR`: throw error * * @throws On `-ERR*` `null` or any other value */ async function fromResp2ToBool(result) { const res = await result; switch (res) { case 1: case 'OK': return true; case 0: return false; case null: throw new Error('Redis operation error detected (value was null).'); default: if (res.toString().startsWith('-ERR')) { throw new InternalServerError_1.InternalServerError(`Redis error: ${res.toString().slice(5)}`); } else { throw new InternalServerError_1.InternalServerError(`Unexpected Redis answer received! (${res})`); } } } //# sourceMappingURL=RedisLuaScripts.js.map