Jérémy Derussé
Contributed by Jérémy Derussé in #26232

The Lock component was introduced in Symfony 3.4 to provide a mechanism to create local (filesystem, semaphore) and remote (Redis) locks that provide exclusive access to a shared resource. Although it's one of the newest components, it's already used in projects like Contao CMS and Google Cloud SDK.

One of its key features are the expiring locks, which are released automatically after some amount of time has passed (called TTL for Time To Live). In case of long-running tasks, it's hard to pick the best TTL, so it's common to start with a not too long TTL and then use the refresh() method to reset the TTL to its original value:

1
2
3
4
5
6
7
8
9
$lock->acquire();
try {
    while (!$finished) {
        // perform a small part of the job...
        $lock->refresh();
    }
} finally {
    $lock->release();
}

The problem of refresh() is that when you are working on different kinds of tasks, the refreshed TTL may not be enough for complex tasks. That's why in Symfony 4.1 we improved the refresh() method to allow passing a TTL as its argument. The new TTL is only used for that refresh() call and not the following ones:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// the original TTL is 30 seconds
$lock = $factory->createLock('the-lock-name', 30);
// ...
$lock->acquire();

// refresh the lock for 30 seconds
$lock->refresh();
// do some work...

// refresh the lock for 10 minutes (600 seconds) before a heavy task
$lock->refresh(600);
// do some heavy work...

// the new refresh is for the 30 seconds of the original TTL
$lock->refresh();
// do some work...
Published in #Living on the edge