Fix: Redis race conditions with .set, .delete. and .clear when useRedisSets=true #881
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
When using Redis and
useRedisSets=true
, it's possible to end up with a mismatch between the keys listed in the namespace set and the actual key/values in Redis.Quick Review of Current Functionality
The
set
op takes place in two steps, the key/value is set and then the key is added to the namespace set.The
delete
op takes place in two steps, the key/value is deleted and then the key is removed from the namespace set.The
clear
op takes place in two steps, the keys are retrieved from the namespace set and then they are deleted (including the namespace set itself).Problems can arise when steps become intermixed and state changes take place in between steps 1 of 2 of certain ops.
Example Problem 1 - key/value in Redis but key not listed in namespace set (actual experience)
System 1 calls
set
to save a value and at the same time System 2 callsclear
.Order of ops:
set
step 1 takes place - key/value savedclear
step 1 takes place - all keys in the namespace set are retrieved (except the key from op 1 since it hasn't been added to the namespace set yet)set
step 2 takes place - key is added to namespace setclear
step 2 takes place - all keys retrieved from step 2 are deleted as well as the namespace set itselfThe key in the namespace set gets deleted in error.
Example Problem 2 - key in namespace set, but actual key/value doesn't exist (theoretical)
set
step 1 takes place - key/value saveddelete
step 1 takes place - key/value deleteddelete
step 2 takes place - key deleted from namespace setset
step 2 takes place - key added to namespace setThe key in the namespace set didn't get deleted, in error.
Solution
Run both
set
anddelete
in transactions.For
clear
, using a transaction doesn't seem possible. As an alternative, instead of deleting the entire namespace set in step 2 we can just remove the specific keys that we retrieved from step 1. This will ensure that any new keys added after step 1 will still remain in the namespace set, but if nothing was added then the set will be empty after step 2 and automatically removed by Redis.Please check if the PR fulfills these requirements
What kind of change does this PR introduce? Bug fix