Description
Symfony version(s) affected: 3.4.27
Description
When multiple processes get a lock, the lock expired exception will always appear, no any processes can successfully acquire the lock.
How to reproduce
$store = new RedisStore($redisInstance, 20);
$store = new RetryTillSaveStore($store);
$factory = new Factory($store);
$lock = $factory->createLock('foo', 10);
$lock->acquire(true);
// do something
$lock->release();
Additional context
RedisStore $initialTtl = 20
Assuming the current time is 10:00s
, the process "A" and the process "B" are ready to acquire the lock "foo", "foo" will be released at 10:20;
At 10:20s:
A
successfully acquires the lock, accourding to
The expire time of the key in the redis will be modified to 10:40s
; but since the key expire time in memory is 10:20s
, the A
will exit because the program does not capture LockExpriedException
and then A
will be restart by the supervisor;
At 10:40s:
The B
acquires the lock, and the redis expire time will be modified to 11:00s
, but also because the expire time in memory (10:20s
) timeout, B
will also exit and restart;
After that, A
and B
get the locks in turn, and extend the expiration time by $initialTtl = 20s
. but since the the expiration time in memory is not updated, no process can successfully acquire the lock.