-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Lua Scripting support to nri-redis #109
Conversation
The core will be in Redis.Script
Turns out error messages are important
This is failing bc I misunderstood `eval` in Redis Eval is: EVAL script numkeys key key key arg arg arg Keys here is not the NAME of the argument, as I thought, but rather an input parameter in full There's no named arguments in Redis. I assumed that by reading examples from the C# API Client in the Rate Limiting implementation docs. Args and Keys are referenced like KEYS[1] KEYS[2] KEYS [3] and ARGV[1] ARGV[2] ARGV[3] Let's fix that in the next few commits
e7e63a7
to
4e3fb2a
Compare
Splits up keys and arguments, uses KEYS[1] and ARGV[1] inside luaScript
This required a RedisResult instance for Text
Redis provides a faster API for running scripts, where you: - SCRIPT LOAD "the script" - EVALSHA "script sha1" n_keys [keys] [args] I can't implement this because we'd need to restrict `doRawQuery`. `doRawQuery` is generic for both instances of `RedisCtx` in Hedis: - Transactions: `RedisCtx RedisTx Queued` - Regular queries: `RedisCtx Redis (Either Reply)` I'll need a different approach for this.
Allows us to do the `evalsha -> script load -> evalsha` flow
The Handler eval is better. The only thing it doesn't support is auto-expire, but I'm skeptical it's a good idea to use that with Lua scripts arbitrarily.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Amazing work! I really appreciate us going the extra mile here to make a good interface for this.
A couple things to change below, but nothing deal breaking.
nri-redis/test/Spec/Redis/Script.hs
Outdated
-- We can't test for compile-time errors, but manually test our helpful error message, uncomment | ||
-- the lines below: | ||
-- Test.test "compilation error" <| \_ -> | ||
-- [script|${123}|] | ||
-- |> Expect.equal "Doesn't matter, this won't compile" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sooo, we can in fact test for compile-time errors :)
The basic idea is that you call your function normally (not in a splice), and then there are tools in the Language.Haskell.TH.TestUtils
module which let you run the Q
monad and test the result.
You might want to take a look at what I did in nri-postgresql/test/Enum.hs
way back when I added postgres enum support.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, let's pair if this is something you would want to add!
…-incoherentinstances Patch to avoid using `IncoherentInstances`
I ended up not needing this, but I noticed it was missing and failing tests for nri-postgresql locally
In CI I think the postgres user gets created somehow. Locally it doesn't
Add an API to do Lua scripting to
Nri.Redis
.We have a new Handler function
eval
, which does the recommended dance:EVALSHA ${sha1}
LOAD SCRIPT ${theScript}
EVALSHA ${sha1}
The failure case only happens:
I initially tried to do this as a
Redis.Api
/Internal.Query
, but it didn't work. If I understand semantics of type classes correctly, it won't unlessInternal.Query
is aMonad
, not anApplicative
.Hedis uses a different
RedisResponse
typeclass for scripting results, which has its own decoding thingy. I wrote a few orphaned instances for common data types, likeText
,Int
and()
.Notes:
eval
API supports namespacing of keyseval
API does not support auto-extending key expiry