redis-smq-common
Version:
RedisSMQ Common Library provides many components that are mainly used by RedisSMQ and RedisSMQ Monitor.
206 lines • 7.42 kB
JavaScript
;
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 || (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'),
};
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.RedisClientError('UNKNOWN_REDIS_SERVER_VERSION'));
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.RedisClientError('UNSUPPORTED_REDIS_SERVER_VERSION'));
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);
});
}
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 tasks = [];
const loadedScripts = {};
for (const name in scriptMap) {
if (!RedisClientAbstract.scripts[name]) {
tasks.push((cb) => {
fs_1.default.readFile(scriptMap[name], 'utf8', (err, content) => {
if (err)
return cb(err);
this.loadScript(content, (err, sha) => {
if (err)
return cb(err);
if (!sha)
return cb(new index_js_3.CallbackEmptyReplyError());
loadedScripts[name] = sha;
RedisClientAbstract.scripts[name] = sha;
cb();
});
});
});
}
}
if (!tasks.length)
return cb(null, loadedScripts);
index_js_1.async.series(tasks, (err) => {
if (err)
return cb(err);
cb(null, loadedScripts);
});
}
getScriptId(name) {
const id = RedisClientAbstract.scripts[name];
if (!id) {
return new index_js_5.RedisClientError(`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