From f32ab58a228ebfbbd20d9babf5d4f8dd467c96c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cahid=20Arda=20=C3=96z?= Date: Thu, 23 May 2024 12:22:30 +0300 Subject: [PATCH] Fix Auto-pipeline Proxy Json Issue (#1080) * fix auto-pipeline proxy json issue * fmt * rm ts-ignore --- pkg/auto-pipeline.test.ts | 32 ++++++++++++++++++++++++++++++++ pkg/auto-pipeline.ts | 17 ++++++++++++----- 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/pkg/auto-pipeline.test.ts b/pkg/auto-pipeline.test.ts index f9b659a3..34120530 100644 --- a/pkg/auto-pipeline.test.ts +++ b/pkg/auto-pipeline.test.ts @@ -299,5 +299,37 @@ describe("Auto pipeline", () => { // @ts-expect-error pipelineCounter is not in type but accessible expect(redis.pipelineCounter).toBe(1); }); + + test("should handle JSON commands correctly", async () => { + + const redis = Redis.fromEnv({ + latencyLogging: false, + enableAutoPipelining: true + }); + + // @ts-expect-error pipelineCounter is not in type but accessible + expect(redis.pipelineCounter).toBe(0); + + const res = await Promise.all([ + redis.set("foo1", "bar"), + redis.json.set("baz1", "$", { hello: "world" }), + redis.get("foo1"), + redis.json.get("baz1"), + redis.json.del("baz1"), + redis.json.get("baz1"), + ]) + + // @ts-expect-error pipelineCounter is not in type but accessible + expect(redis.pipelineCounter).toBe(1); + + expect(res).toEqual([ + "OK", + "OK", + "bar", + { hello: "world" }, + 1, + null + ]) + }) }); diff --git a/pkg/auto-pipeline.ts b/pkg/auto-pipeline.ts index 15fd7f1c..a85ecf40 100644 --- a/pkg/auto-pipeline.ts +++ b/pkg/auto-pipeline.ts @@ -6,7 +6,7 @@ import { CommandArgs } from "./types"; // properties which are only available in redis type redisOnly = Exclude; -export function createAutoPipelineProxy(_redis: Redis) { +export function createAutoPipelineProxy(_redis: Redis, json?: boolean): Redis { const redis = _redis as Redis & { autoPipelineExecutor: AutoPipelineExecutor; }; @@ -22,6 +22,10 @@ export function createAutoPipelineProxy(_redis: Redis) { return redis.autoPipelineExecutor.pipelineCounter; } + if (command === "json") { + return createAutoPipelineProxy(redis, true); + }; + const commandInRedisButNotPipeline = command in redis && !(command in redis.autoPipelineExecutor.pipeline); @@ -29,20 +33,23 @@ export function createAutoPipelineProxy(_redis: Redis) { return redis[command as redisOnly]; } - command = command as keyof Pipeline; // If the method is a function on the pipeline, wrap it with the executor logic - if (typeof redis.autoPipelineExecutor.pipeline[command] === "function") { + if (typeof redis.autoPipelineExecutor.pipeline[command as keyof Pipeline] === "function") { return (...args: CommandArgs) => { // pass the function as a callback return redis.autoPipelineExecutor.withAutoPipeline((pipeline) => { - (pipeline[command] as Function)(...args); + if (json) { + (pipeline.json[command as keyof Pipeline["json"]] as Function)(...args) + } else { + (pipeline[command as keyof Pipeline] as Function)(...args); + } }); }; } // if the property is not a function, a property of redis or "pipelineCounter" // simply return it from pipeline - return redis.autoPipelineExecutor.pipeline[command]; + return redis.autoPipelineExecutor.pipeline[command as keyof Pipeline]; }, }) as Redis; }