Skip to content

Commit bc1b168

Browse files
marcbachmannluin
authored andcommitted
fix: Fix the NOSCRIPT behavior when using pipelines
1 parent 60c2af9 commit bc1b168

File tree

2 files changed

+30
-30
lines changed

2 files changed

+30
-30
lines changed

Diff for: lib/script.ts

+13-18
Original file line numberDiff line numberDiff line change
@@ -41,26 +41,21 @@ export default class Script {
4141

4242
const evalsha = new Command("evalsha", [this.sha].concat(args), options);
4343
evalsha.isCustomCommand = true;
44+
evalsha.promise = evalsha.promise.catch((err: Error) => {
45+
if (err.toString().indexOf("NOSCRIPT") === -1) {
46+
throw err;
47+
}
48+
const command = new Command("eval", [this.lua].concat(args), options);
49+
if (container.isPipeline === true) container.redis.sendCommand(command);
50+
else container.sendCommand(command);
51+
return command.promise;
52+
});
4453

45-
const result = container.sendCommand(evalsha);
46-
if (isPromise(result)) {
47-
return asCallback(
48-
result.catch((err: Error) => {
49-
if (err.toString().indexOf("NOSCRIPT") === -1) {
50-
throw err;
51-
}
52-
return container.sendCommand(
53-
new Command("eval", [this.lua].concat(args), options)
54-
);
55-
}),
56-
callback
57-
);
58-
}
59-
60-
// result is not a Promise--probably returned from a pipeline chain; however,
61-
// we still need the callback to fire when the script is evaluated
6254
asCallback(evalsha.promise, callback);
6355

64-
return result;
56+
// The result here is one of
57+
// - a Promise when executed on the redis instance
58+
// - a pipeline instance in pipeline mode
59+
return container.sendCommand(evalsha);
6560
}
6661
}

Diff for: test/functional/pipeline.ts

+17-12
Original file line numberDiff line numberDiff line change
@@ -357,14 +357,16 @@ describe("pipeline", function () {
357357
it("should reload scripts on redis restart (reconnect)", async function () {
358358
const redis = new Redis({ connectionName: "load-script-on-reconnect" });
359359
const redis2 = new Redis();
360-
redis.defineCommand("exeecafterreconnect", {
360+
redis.defineCommand("execafterreconnect", {
361361
numberOfKeys: 0,
362-
lua: `return "OK"`,
362+
lua: `return "Foo"`,
363363
});
364364

365-
const [[err, res]] = await redis.multi([["exeecafterreconnect"]]).exec();
365+
const [[err, res]] = await redis
366+
.pipeline([["execafterreconnect"]])
367+
.exec();
366368
expect(err).to.equal(null);
367-
expect(res).to.equal("OK");
369+
expect(res).to.equal("Foo");
368370

369371
const client = await redis.client("list").then((clients) => {
370372
const myInfo = clients
@@ -378,16 +380,19 @@ describe("pipeline", function () {
378380
await redis2.script("flush");
379381
await redis2.client("kill", "addr", client);
380382

381-
// Wait for reconnect, at the moment scripts are not loaded
382-
// if the pipeline starts before ioredis reconnects
383-
await redis.ping();
384-
385-
const [[err2, res2]] = await redis
386-
.multi([["exeecafterreconnect"]])
383+
const res2 = await redis
384+
.pipeline([
385+
["set", "foo", "bar"],
386+
["execafterreconnect"],
387+
["get", "foo"],
388+
])
387389
.exec();
388390

389-
expect(err2).to.equal(null);
390-
expect(res2).to.equal("OK");
391+
expect(res2).to.deep.equal([
392+
[null, "OK"],
393+
[null, "Foo"],
394+
[null, "bar"],
395+
]);
391396
redis.disconnect();
392397
redis2.disconnect();
393398
});

0 commit comments

Comments
 (0)