For now following code is used:
!$this->lockMayBeAvailable($name) && $this->memcache->set($key, $lock_id, $timeout)
I havent tested it yet, but looks like we can have the sort of race condition here, because there are not transactions or like so, just "get" and "set".
Possibly, we can use "add" method instead of "set" to be sure, that "lock key" was not already set.
It will require to use "delete" instead of "set FALSE value" to work with "add" method correctly.
| Comment | File | Size | Author |
|---|---|---|---|
| #9 | interdiff-2905341-9.txt | 968 bytes | damiankloip |
| #9 | 2905341-9.patch | 3.13 KB | damiankloip |
| #7 | 2905341-7.patch | 3.24 KB | damiankloip |
Comments
Comment #2
Evgeny_Yudkin commentedComment #3
webchickTagging as a beta blocker, per #2989594: [META] Create a stable release of Memcache module for Drupal 8.
Comment #4
damienmckennaWould this cause the problem with Acquia production instances failing, because they're connecting to multiple memcache instances?
Comment #5
fabianx commentedI agree, this is just plain wrong:
D7 code for reference:
Marking as critical as a non-atomic lock implementation is a recipe for disaster.
Comment #6
fabianx commentedNote from code review:
- PersistentMemcacheLockBackend will have a lot of trouble to be correct
Memcache is non-volatile storage and it can evict any key at any time, which does not combine with potentially long-lived locks (as persistent seems to imply:
I suggest we do defer to the database for that and do not implement it. If it is for across page requests, then it should be fine to live in the database as that should mostly be used for admin things, etc.
The problem is:
If the key or keys are not there, we cannot assume that the lock is not taken, but we also cannot assume that the lock is taken. We are in an unknown state.
For normal locks the same problem exists, but as they are way more short-lived (usually just to rebuild some data / caches), the chances of eviction are way way less. Indeed so less, that we've not seen any such problems on sites in years.
The persistent lock could in theory be made more safe by putting different sized items into the different memcache slabs (after we have the lock) and do a check if any of those items still exist before acquiring the lock - to detect the evicted lock.
That could in theory make this work - will speak with Narayan again about it today - if putting in several slabs would make us more safe here.
I also suggest we open a follow-up for the persistent lock discussion ;).
Comment #7
damiankloip commentedMy fault for the initial (very quick) implementation many years ago :)
Here is a patch to us add() (wasn't previously a part of our abstracted memcache wrapper API).
Agree, the persistent lock is probably not a good idea. Might be an idea to consider removing it. It was mainly copied from core lock previously...
Comment #8
fabianx commentedThat's unrelated, but why not put the collectStats in $this in __construct?
Also I think stat collection should be a decorator around the class, not hard-coded as we have the possibility to do so here.
Can we open a ticket for that?
Not really, we can only extend with set ;), that's the wrong line to change.
Not opposed, but: Why this change?
Comment #9
damiankloip commentedUgh - yes.
1. Yes, let's open a ticket for it to discuss
2. Fixed!
3. Just because it's easier to read, sneaking in....
Comment #10
damiankloip commentedAdded #2995907: Remove Persistent Lock Implementation for the removal of the persistent lock
Comment #11
fabianx commentedRTBC - lets get this in
Comment #13
damiankloip commentedComment #14
catchFollow-up for statistics collection as decorator here: #2996054: Refactor statistics collection to a decorator agreed that'd be a good change to make.