redis-smq-common
Version:
Provides essential components and utilities shared across RedisSMQ packages.
70 lines • 3.5 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.withWatchTransaction = withWatchTransaction;
const index_js_1 = require("./errors/index.js");
const index_js_2 = require("../errors/index.js");
function withWatchTransaction(client, attemptFn, callback, options) {
var _a;
const maxAttempts = (_a = options === null || options === void 0 ? void 0 : options.maxAttempts) !== null && _a !== void 0 ? _a : 3;
const doAttempt = (attemptNo) => {
var _a, _b;
if (attemptNo > maxAttempts) {
const err = (_b = (_a = options === null || options === void 0 ? void 0 : options.makeRetryExceededError) === null || _a === void 0 ? void 0 : _a.call(options)) !== null && _b !== void 0 ? _b : new index_js_1.WatchTransactionMaxRetriesExceeded();
return callback(err);
}
const watch = (keys, cb) => {
const arr = Array.isArray(keys) ? keys : [keys];
if (arr.length === 0)
return cb();
client.watch(arr, (err) => {
if (err && (options === null || options === void 0 ? void 0 : options.onWatchError))
options.onWatchError(err);
cb(err || null);
});
};
attemptFn(client, watch, (attemptErr, result) => {
if (attemptErr) {
return client.unwatch(() => callback(attemptErr));
}
if (!result || !result.multi) {
return client.unwatch(() => callback(new index_js_2.CallbackEmptyReplyError({
message: 'Invalid attempt result. Expected a result object with a "multi" key.',
})));
}
result.multi.exec((execErr, execRes) => {
var _a;
if (execErr) {
if (execErr instanceof index_js_1.WatchedKeysChangedError) {
(_a = options === null || options === void 0 ? void 0 : options.onRetry) === null || _a === void 0 ? void 0 : _a.call(options, attemptNo, maxAttempts);
return client.unwatch(() => {
var _a;
const backoff = (_a = options === null || options === void 0 ? void 0 : options.backoff) !== null && _a !== void 0 ? _a : ((n) => n * 1000);
const delay = backoff(attemptNo);
if (delay && delay > 0) {
setTimeout(() => doAttempt(attemptNo + 1), delay);
}
else {
doAttempt(attemptNo + 1);
}
});
}
if (options === null || options === void 0 ? void 0 : options.onExecError)
options.onExecError(execErr);
return client.unwatch(() => callback(execErr));
}
if (result.afterExec) {
try {
result.afterExec(execRes !== null && execRes !== void 0 ? execRes : []);
}
catch (e) {
const err = e instanceof Error ? e : new Error(String(e));
return callback(err);
}
}
callback(null, execRes);
});
});
};
doAttempt(1);
}
//# sourceMappingURL=with-watch-transaction.js.map