-
Notifications
You must be signed in to change notification settings - Fork 701
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
[BUG] evalSha not working the same as in Redis #1537
Comments
There have been some changes to the script cache over the years. I don't remember exactly when each change happened, but both of changes below were made in Redis when it was still open source, before Valkey was forked, but one the second one was only released in Valkey 8 (and Redis 7.4 probably).
I don't know if these are reasons for your problems, but in any case, I think you should always handle the NOSCRIPT error by EVASHA and fallback to EVAL or SCRIPT LOAD. The script cache is just a cache. You shouldn't rely on scripts remaining cached forever. |
TL;DR The problem is caused by a change made to Valkey in https://github.com/valkey-io/valkey/pull/617/files#diff-1abc5651133d108c0c420d9411925373c711133e7748d9e4f4c97d5fb543fdd9L1819-R1819, which changed the error string returned by I've debugged the issue and the problem is indeed in a change made to Valkey, which changed the error string returned by What's happening is that symfony is trying to evaluate a Lua script, and the function that implements the execution of Lua scripts in redis/valkey first tries to run To check that if (self::NO_SCRIPT_ERROR_MESSAGE !== $e->getMessage()) {
throw new LockStorageException($err);
}
// otherwise add the script with SCRIPT LOAD And private const NO_SCRIPT_ERROR_MESSAGE = 'NOSCRIPT No matching script. Please use EVAL.'; The problem is that in Valkey 8, the PR #617 changed the error message for the So basically we've changed a user-facing error message in 8.0, which is breaking other software that relies on it. @zuiderkwast should we fix this by re-adding the removed suffix? And then backport it? |
I think we should. Application compatibility is such a bugger to get right, it seems like we should continue to be as consistent as possible with Redis. |
I guess the reason we removed "Please use EVAL" is that "SCRIPT LOAD" can also be used for loading a script. It's a small breaking change and it was done in a major release, right? Applications should
So we can never change any formulation in any error message without considering it a breaking change then? We have replaced "Redis" with "Valkey" in a number of error messages in our first release.... I would hope we could just make the documentation more clear, such that clients shall match only the first uppercase word and MUST NOT match the full text. |
I agree. I think we were within our right to do it. I guess my point is we didn't really need to change this one, the only reason we did it was to be generic. We could have introduced a new error message just for the new command. |
"within our right" - yes That said, I agree with @madolson that it is in our best interests to eliminate migration frictions whenever possible. |
I think you're right. We can't rely on clients only checking the first word of the error. In many cases checking the first word is not enough, because many errors don't have a proper tag. Then the client needs to check the full text. Example: I agree we should avoid changing error messages. When we do, I think we shall list them as breaking changes from now on. Regarding reverting this particular error message, I don't have a strong opinion. |
We are considering to contribute a PR to Symfony Lock component to make it as robust as possible. Would it be correct then from your perspective to check if the message begins with "NOSCRIPT " instead of as today check the full message? For all other cases an expection is thrown (like today if it isn't matching exactly). Would this be a more robust implementation for both Valkey and Redis or do you see problems with that? |
@johanwilfer Yes, we recommended this way to check errors. It is more robust. |
Ok, I'll work on the PR next week then. Thanks a lot for your insights! |
FYI: The PR for symfony is there: symfony/symfony#59488 |
Describe the bug
We have PHP application using symfony/lock. Version 6.4 works fine, as it's using
eval
. Version 7.2 and beyond useevalSha
under the hood.It works fine for Redis 6.2, 7.2 and so on. It didn't work well for Valkey 8 (7.2.4 redis version).
Lock::acquire
attempt for Redis returnstrue
, for Valkeyfalse
.In the previous version (using
eval
) it works fine.Is there any significant difference between
evalSha
of Valkey and Redis?Reference: symfony/symfony#59387
To reproduce
I've made a repository that allows you to reproduce it: https://github.com/PatNowak/symfony-valkey-poc.
Long story short:
It will by default use
symfony/lock
in the version7.2
that useevalSha
under the hood.To downgrade the version please do:
You can also check it works fine (before downgrading) on the Redis:
I left the comments in the repository README.md file.
Expected behavior
The
evalSha
will work the same as in the Redis.Additional information
I referenced the issue in the Symfony, as first I suspected something on their side. I also tested both PHP redis connectors -
phpredis
andpredis
. No difference.The text was updated successfully, but these errors were encountered: