The CriticalSection
is a simple object that handles the critical section overhead for you
and lets you focus on the actual code.
use PetrKnap\CriticalSection\CriticalSection;
use Symfony\Component\Lock\NoLock;
$lock = new NoLock();
$criticalOutput = CriticalSection::withLock($lock)(fn () => 'This was critical.');
var_dump($criticalOutput);
You can wrap critical sections one inside the other thanks to the WrappingCriticalSection
.
This makes it easy to combine multiple locks, for example.
use PetrKnap\CriticalSection\CriticalSection;
use Symfony\Component\Lock\NoLock;
$lockA = new NoLock();
$lockB = new NoLock();
$criticalOutput = CriticalSection::withLock($lockA)->withLock($lockB)(fn () => 'This was critical.');
var_dump($criticalOutput);
You can also pass locks as array and leave the composition to the critical section.
use PetrKnap\CriticalSection\CriticalSection;
use Symfony\Component\Lock\NoLock;
$lockA = new NoLock();
$lockB = new NoLock();
$criticalOutput = CriticalSection::withLocks([$lockA, $lockB])(fn () => 'This was critical.');
var_dump($criticalOutput);
Use the LockedResource
if you need to be sure that you are not processing resource outside it's critical section.
namespace PetrKnap\CriticalSection;
use Symfony\Component\Lock\NoLock;
/** @param Locked<Some\Resource> $resource */
function f(LockedResource $resource) {
echo $resource->value;
}
$lock = new NoLock();
$resource = LockableResource::of(new Some\Resource('data'), $lock);
CriticalSection::withLock($lock)(fn () => f($resource));
Use the doctrine/dbal
and its transactional
method.
/** @var PetrKnap\CriticalSection\CriticalSectionInterface $criticalSection */
/** @var Doctrine\DBAL\Connection $connection */
$criticalSection(
fn () => $connection->transactional(
fn () => 'This was critical on DB server.'
)
);
Always use transactional
inside critical section to prevent starvation.
Run composer require petrknap/critical-section
to install it.
You can support this project via donation.
The project is licensed under the terms of the LGPL-3.0-or-later
.