-
-
Notifications
You must be signed in to change notification settings - Fork 9.5k
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
[RFC][lock] Introduce Shared Lock (or Read/Write Lock) #37752
Conversation
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.
Do stores deal properly with an upgrade scenario, where the store might contain existing locks created using the old format for the state ?
Good point. For sure, they have to. |
I know they have to. The question is whether they actually do. To test this, we would need to write some lock in the old format in Redis (or whatever storage) and then try to acquire the same lock with the new code and ensure it does not break but properly detects a conflict. For a local test, what you can do is creating 2 projects: one using symfony/lock 5.1 to acquire the lock and hold it, and another one using your new code and trying to acquire a (conflicting) lock (should be tested with both |
I tested compatibility locally with 2 clients (with different versions) at the same time and it worked in both way. I also added a integration test that reuse the old code to assert it for Redis. |
@jderusse Just for my information, the next step here is to implement the feature in other stores? |
That was my first idea. But it's more complicated than I thought, and PR might be harder to review. I suggest:
|
Having this feature available for some stores only is fine by me. |
@jderusse Having additionnal stores in other PRs is a good idea. Can you finish this one without other stores? |
local uniqueToken = ARGV[1] | ||
local ttl = tonumber(ARGV[2]) | ||
|
||
local now = redis.call("TIME") |
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.
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.
In semaphore I used the server's time. I think it's more reliable than hopping user are running redis > 5.X
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.
Oh, I did not realized that the script of REDIS < 5 was broken because of that.
Thanks for the confirmation, I've refactored this part.
151a090
to
f0feb6d
Compare
PR is ready for review, with the current 2 stores (flock, redis) |
7679a1e
to
c1a8862
Compare
local uniqueToken = ARGV[2] | ||
local ttl = tonumber(ARGV[3]) | ||
|
||
-- asserts the KEY is compatible with current version (old Symfony <5.2 BC) |
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.
This check provide backward compatibility:
- when an old version of symfony put a lock, the new version won't be able to put a lock.
But the opposite is not (always) true:
- with predis: when a new version of symfony put a lock, the old version will fail with an ServerException
- with phpredis it's ok: when an new version of symfony put a lock, the old version won't be able to put a lock.
Both situation are safe (user won't be able to acquire the lock), but the complexity of the code to throw a proper "LockConfictException" instead of "predis\ServerException" don't worth it IMHO
a50509e
to
4789f54
Compare
Thank you @jderusse. |
…usse) This PR was merged into the master branch. Discussion ---------- [Lock] Add documentation about Shared Locks Fixes symfony#14225 implemented in symfony/symfony#37752 Commits ------- dfd97c5 Add documentation about read/write locks
This PR adds a new method "acquireRead" to the Lock class in order to solve the single writer multiple readers problem.
usage:
next steps
add more stores
Priority policies
Priority policy (read-preffering or write preffering) is not covered by this PR.
Promote/Demote
Converting a Read lock to Write Lock (promote) or Write lock to Read lock (demote) is covered by calling
acquireRead
/acquired
method.