From d9d877fee72d1c32744716a315cee74fc9027c1d Mon Sep 17 00:00:00 2001 From: Osama Sayegh Date: Wed, 6 Oct 2021 17:42:04 +0300 Subject: [PATCH] DEV: Pass kwargs to the redis gem when calling methods/commands that we don't wrap (#14530) This commit fixes the `eval` and `evalsha` commands/methods and any other methods that don't have a wrapper in `DiscourseRedis` and expect keyword arguments. I noticed this problem in Logster when I was trying to fetch some log messages in JSON format using the rails console and saw the messages were missing the `env` field. Logster uses the `eval` command to fetch messages `env`s: https://github.com/discourse/logster/blob/dc351fd00f283db212696c940ef3a456efc42ccb/lib/logster/redis_store.rb#L250-L253 and that code was not fetching anything because `DiscourseRedis` didn't pass the `keys` keyword arg to the redis gem. --- lib/discourse_redis.rb | 2 +- spec/components/discourse_redis_spec.rb | 53 +++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/lib/discourse_redis.rb b/lib/discourse_redis.rb index 341f3d131c5..1ed8fc6a5ed 100644 --- a/lib/discourse_redis.rb +++ b/lib/discourse_redis.rb @@ -39,7 +39,7 @@ class DiscourseRedis # prefix the key with the namespace def method_missing(meth, *args, **kwargs, &block) if @redis.respond_to?(meth) - DiscourseRedis.ignore_readonly { @redis.public_send(meth, *args, &block) } + DiscourseRedis.ignore_readonly { @redis.public_send(meth, *args, **kwargs, &block) } else super end diff --git a/spec/components/discourse_redis_spec.rb b/spec/components/discourse_redis_spec.rb index 8156a573ec2..aa8684d1b9a 100644 --- a/spec/components/discourse_redis_spec.rb +++ b/spec/components/discourse_redis_spec.rb @@ -78,5 +78,58 @@ describe DiscourseRedis do expect(Discourse.recently_readonly?).to eq(true) end end + + describe "#eval" do + it "keys and arvg are passed correcty" do + keys = ["key1", "key2"] + argv = ["arg1", "arg2"] + + expect(Discourse.redis.eval( + "return { KEYS, ARGV };", + keys: keys, + argv: argv, + )).to eq([keys, argv]) + + expect(Discourse.redis.eval( + "return { KEYS, ARGV };", + keys, + argv: argv, + )).to eq([keys, argv]) + + expect(Discourse.redis.eval( + "return { KEYS, ARGV };", + keys, + argv, + )).to eq([keys, argv]) + end + end + + describe "#evalsha" do + it "keys and arvg are passed correcty" do + keys = ["key1", "key2"] + argv = ["arg1", "arg2"] + + script = "return { KEYS, ARGV };" + Discourse.redis.script(:load, script) + sha = Digest::SHA1.hexdigest(script) + expect(Discourse.redis.evalsha( + sha, + keys: keys, + argv: argv, + )).to eq([keys, argv]) + + expect(Discourse.redis.evalsha( + sha, + keys, + argv: argv, + )).to eq([keys, argv]) + + expect(Discourse.redis.evalsha( + sha, + keys, + argv, + )).to eq([keys, argv]) + end + end end end