From 4bf0be7242d5a24cd15366c7811b2baf0093f5a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cahid=20Arda=20=C3=96z?= Date: Thu, 4 Jul 2024 10:15:37 +0300 Subject: [PATCH] fix: resolve arrappend issue (#1165) when a redis method which is available in .json but not available in the pipeline is used while auto pipeline is enabled, proxy doesn't check properly that the method is a function and attempts to return from pipeline, instead of pipeline.json. --- pkg/auto-pipeline.test.ts | 6 ++++-- pkg/auto-pipeline.ts | 5 ++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/pkg/auto-pipeline.test.ts b/pkg/auto-pipeline.test.ts index 335e4888..24810f08 100644 --- a/pkg/auto-pipeline.test.ts +++ b/pkg/auto-pipeline.test.ts @@ -13,6 +13,7 @@ describe("Auto pipeline", () => { test("should execute all commands inside a Promise.all in a single pipeline", async () => { const persistentKey = newKey(); const persistentKey2 = newKey(); + const persistentKey3 = newKey(); const scriptHash = await new ScriptLoadCommand(["return 1"]).exec(client); const redis = Redis.fromEnv({ @@ -143,10 +144,11 @@ describe("Auto pipeline", () => { redis.zscore(newKey(), "member"), redis.zunionstore(newKey(), 1, [newKey()]), redis.zunion(1, [newKey()]), - redis.json.set(newKey(), "$", { hello: "world" }), + redis.json.set(persistentKey3, '$', { log: ["one", "two"] }), + redis.json.arrappend(persistentKey3, "$.log", '"three"'), ]); expect(result).toBeTruthy(); - expect(result.length).toBe(120); // returns + expect(result.length).toBe(121); // returns // @ts-expect-error pipelineCounter is not in type but accessible120 results expect(redis.pipelineCounter).toBe(1); }); diff --git a/pkg/auto-pipeline.ts b/pkg/auto-pipeline.ts index 18731a39..8fddbb64 100644 --- a/pkg/auto-pipeline.ts +++ b/pkg/auto-pipeline.ts @@ -34,7 +34,10 @@ export function createAutoPipelineProxy(_redis: Redis, json?: boolean): Redis { } // If the method is a function on the pipeline, wrap it with the executor logic - if (typeof redis.autoPipelineExecutor.pipeline[command as keyof Pipeline] === "function") { + const isFunction = json + ? typeof redis.autoPipelineExecutor.pipeline.json[command as keyof Pipeline["json"]] === "function" + : typeof redis.autoPipelineExecutor.pipeline[command as keyof Pipeline] === "function" + if (isFunction) { return (...args: CommandArgs) => { // pass the function as a callback return redis.autoPipelineExecutor.withAutoPipeline((pipeline) => {