-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Allow LoadedLuaScript fail-over in case the Redis instance is restarted #2170
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
Allow LoadedLuaScript fail-over in case the Redis instance is restarted #2170
Conversation
|
I've had a look at this, and: I think this PR is doing a great job of illustrating the problem, but I'm not sure it is the best direction for the solution. From what I can see, I think we can fix everything here much more simply and consistently, simply by changing (as a side note: if we did that, we should probably mark the the exposed There is a pre-existing inconsistency between the sync and async versions of Thoughts? |
|
Thanks Mark, I am all for simplicity :). If your approach is still able to internally reconstruct and reuse the hash, then it's a better, simpler approach. I will give this a shot after the weekend. |
|
@mgravell , I did take a look at the implementation and I think the approach you proposed should work as we will be hitting this code-path (the hashed value is sent):
The only remaining problem is the
Are we OK with expanding the public API or should I stick with the Edit: |
|
Re key prefix; the existing implementation also didn't use any privileged APIs - it just expanded them as part of Re |
Yeah, silly me didn't notice that we can just reuse the existing helper. Fixed.
Fine by me, are we OK with not using the SHA hash at all then in this code path? I noticed this piece: ResultProcessor.ScriptLoadProcessor.IsSHA1(script) ? RedisCommand.EVALSHA : RedisCommand.EVALIs it OK if we run |
|
|
||
| try | ||
| { | ||
| return await ExecuteAsync(msg, ResultProcessor.ScriptResult, defaultValue: RedisResult.NullSingle); |
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.
I just copied the ScriptEvaluate, however not sure if the fallback is even needed here.
When debugging and restarting the Redis the catch branch was never reached and we recovered normally.
|
@mgravell Do you think we can still re-use the hash in The problem is how to propagate the information about the missing script from the evaluation call using hash: Two options comes to mind:
WDYT? |
| /// <param name="flags">The flags to use for this operation.</param> | ||
| /// <returns>A dynamic representation of the script's result.</returns> | ||
| /// <remarks><seealso href="https://redis.io/commands/evalsha"/></remarks> | ||
| /// <remarks>Please do not use this overload as it's not resilient to Redis server restarts. Use <see cref="ScriptEvaluate(string, RedisKey[], RedisValue[], CommandFlags)"/> instead.</remarks> |
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.
I think it is fine to offer this as an advisory comment, but: I'd hesitate to say "please do not" - more just something that gives relevant warning; ditto on the EditorBrowsableState.Never
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.
Done.
|
I'd much rather not make the API change here - meaning: the new API added that passes 1000000 tests: 81ms If we assume that almost all non-SHA scripts aren't exactly 40 characters, we can add a length test: internal static bool IsSHA1(string? script) => script is not null && script.Length == 40 && sha1.IsMatch(script);and we get: 1000000 tests: 0ms I'd much rather do that, and keep the API simple; thoughts? |
|
(FWIW: I experimented with a manually rolled test of the actual character test - no significant improvement, so: no point rewriting that IMO - just leave it as regex; it turns out that regex has been optimized pretty well for this type of scenario) |
How about we do these changes:
|
|
If you're asking about hiding the hash property: yes, we can safely IMO hide that in every way - [Browsable], [EditorBrowsable] and [Obsolete] (with the latter as a warning only, not an error). Sound good? |
And what do you think about hiding everything around The only real added value is that script pre-load which can be done by: server.ScriptLoad(LuaScript.ExecutableScript, flags) |
|
It's a great question, but I think I'd rather defer on that for now |
Sounds good, pushed the changes and reverted any API additions. Let me know if the approach is OK, then I'll focus on tests. |
mgravell
left a comment
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.
approach looks good 👍
|
Can you please add the |
Done. |
|
@mgravell Pushed the changes. Anything left to address? Unfortunately, some random tests failed on Ubuntu should I just retry? |
NickCraver
left a comment
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.
Current looks good - thanks for the iterations on this to make it non-breaking and beneficial at the same time :)
Motivation
We want to take advantage of sending just hashed
LoadedLuaScriptto a server, but still, be able automatically failover and reconstruct the hash in case the Redis instance restarts.The goal was not to change the public API surface.
Adresses #1968
Unit tests are still missing, first I want to check with you guys whether this is the right approach.