petrknap / critical-section
Critical section based on `symfony/lock`
Fund package maintenance!
Other
Requires
- php: >=8.0
- symfony/lock: ^6.0
Requires (Dev)
- nunomaduro/phpinsights: ^2.11
- petrknap/shorts: ^2.1
- phpstan/phpstan: ^1.10
- phpunit/phpunit: ^9.6
- squizlabs/php_codesniffer: ^3.7
README
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);
Does your critical section work with database?
Use 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
.