UNPKG

redis-smq-common

Version:

Provides essential components and utilities shared across RedisSMQ packages.

227 lines 8.29 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.RedisClientAbstract = exports.ELuaScriptName = void 0; const fs_1 = __importDefault(require("fs")); const path_1 = require("path"); const index_js_1 = require("../../async/index.js"); const index_js_2 = require("../../env/index.js"); const index_js_3 = require("../../errors/index.js"); const index_js_4 = require("../../event/index.js"); const index_js_5 = require("../errors/index.js"); const dir = index_js_2.env.getCurrentDir(); var ELuaScriptName; (function (ELuaScriptName) { ELuaScriptName["LPOPRPUSH"] = "LPOPRPUSH"; ELuaScriptName["ZPOPRPUSH"] = "ZPOPRPUSH"; ELuaScriptName["ZPOPLPUSH"] = "ZPOPLPUSH"; })(ELuaScriptName || (exports.ELuaScriptName = ELuaScriptName = {})); const luaScriptMap = { [ELuaScriptName.LPOPRPUSH]: (0, path_1.resolve)(dir, '../lua-scripts/lpoprpush.lua'), [ELuaScriptName.ZPOPRPUSH]: (0, path_1.resolve)(dir, '../lua-scripts/zpoprpush.lua'), [ELuaScriptName.ZPOPLPUSH]: (0, path_1.resolve)(dir, '../lua-scripts/zpoplpush.lua'), }; const minimalSupportedVersion = [4, 0, 0]; class RedisClientAbstract extends index_js_4.EventEmitter { constructor() { super(...arguments); this.connectionClosed = true; } init() { index_js_1.async.series([ (cb) => this.validateRedisServerSupport(cb), (cb) => this.loadBuiltInScriptFiles(cb), ], (err) => { if (err) this.emit('error', err); else this.emit('ready'); }); } validateRedisVersion(major, feature = 0, minor = 0) { if (!RedisClientAbstract.redisServerVersion) { this.emit('error', new index_js_5.UnknownRedisServerVersionError()); return false; } return (RedisClientAbstract.redisServerVersion[0] > major || (RedisClientAbstract.redisServerVersion[0] === major && RedisClientAbstract.redisServerVersion[1] >= feature && RedisClientAbstract.redisServerVersion[2] >= minor)); } validateRedisServerSupport(cb) { const validate = (cb) => { const [major, feature, minor] = minimalSupportedVersion; if (!this.validateRedisVersion(major, feature, minor)) cb(new index_js_5.UnsupportedRedisServerVersionError()); else cb(); }; if (!RedisClientAbstract.redisServerVersion) { this.updateServerVersion((err) => { if (err) cb(err); else validate(cb); }); } else validate(cb); } sscanAll(key, options, cb) { const result = new Set(); const iterate = (cursor) => { this.sscan(key, cursor, options, (err, reply) => { if (err) cb(err); else if (!reply) cb(new index_js_3.CallbackEmptyReplyError()); else { reply.items.forEach((i) => result.add(i)); if (reply.cursor === '0') cb(null, [...result]); else iterate(reply.cursor); } }); }; iterate('0'); } hscanAll(key, options, cb) { const result = {}; const iterate = (cursor) => { this.hscan(key, cursor, options, (err, reply) => { if (err) cb(err); else if (!reply) cb(new index_js_3.CallbackEmptyReplyError()); else { Object.assign(result, reply.result); if (reply.cursor === '0') cb(null, result); else iterate(reply.cursor); } }); }; iterate('0'); } zpoprpush(source, destination, cb) { this.runScript(ELuaScriptName.ZPOPRPUSH, [source, destination], [], (err, res) => { if (err) cb(err); else cb(null, typeof res === 'string' ? res : null); }); } zpoplpush(source, destination, cb) { this.runScript(ELuaScriptName.ZPOPLPUSH, [source, destination], [], (err, res) => { if (err) cb(err); else cb(null, typeof res === 'string' ? res : null); }); } lpoprpush(source, destination, cb) { if (this.validateRedisVersion(6, 2)) { this.lmove(source, destination, 'LEFT', 'RIGHT', cb); } else { this.runScript(ELuaScriptName.LPOPRPUSH, [source, destination], [], (err, res) => { if (err) cb(err); else cb(null, typeof res === 'string' ? res : null); }); } } updateServerVersion(cb) { if (!RedisClientAbstract.redisServerVersion) { this.getInfo((err, res) => { if (err) cb(err); else if (!res) cb(new index_js_3.CallbackEmptyReplyError()); else { RedisClientAbstract.redisServerVersion = res .split('\r\n')[1] .split(':')[1] .split('.') .map((i) => Number(i)); cb(); } }); } else cb(); } loadBuiltInScriptFiles(cb) { this.loadScriptFiles(luaScriptMap, (err) => cb(err)); } loadScriptFiles(scriptMap, cb) { const scriptsToLoad = {}; const loadedScripts = {}; for (const name in scriptMap) { const sha = RedisClientAbstract.scripts[name]; if (sha) { loadedScripts[name] = sha; } else { scriptsToLoad[name] = scriptMap[name]; } } if (Object.keys(scriptsToLoad).length === 0) { return cb(null, loadedScripts); } index_js_1.async.eachIn(scriptsToLoad, (scripts, name, taskCallback) => { const scriptsArr = Array.isArray(scripts) ? scripts : [scripts]; index_js_1.async.map(scriptsArr, (file, mapCallback) => fs_1.default.readFile(file, 'utf8', mapCallback), 10, (err, contents) => { if (err) return taskCallback(err); if (!contents) return cb(new index_js_3.CallbackEmptyReplyError()); const scriptContent = contents.join('\n'); this.loadScript(scriptContent, (err, sha) => { if (err) return taskCallback(err); if (!sha) return taskCallback(new index_js_3.CallbackEmptyReplyError()); loadedScripts[name] = sha; RedisClientAbstract.scripts[name] = sha; taskCallback(); }); }); }, (err) => { if (err) return cb(err); cb(null, loadedScripts); }); } getScriptId(name) { const id = RedisClientAbstract.scripts[name]; if (!id) { return new index_js_3.PanicError({ message: `ID of script [${name}] is missing`, }); } return id; } runScript(scriptName, keys, args, cb) { const sha = this.getScriptId(scriptName); if (sha instanceof Error) cb(sha); else { this.evalsha(sha, [keys.length, ...keys, ...args], (err, res) => { if (err) cb(err); else cb(null, res); }); } } } exports.RedisClientAbstract = RedisClientAbstract; RedisClientAbstract.scripts = {}; RedisClientAbstract.redisServerVersion = null; //# sourceMappingURL=redis-client-abstract.js.map