petrknap/critical-section

基于 `symfony/lock` 的临界区

v2.1.0 2024-06-29 17:35 UTC

This package is auto-updated.

Last update: 2024-09-22 14:45:49 UTC


README

The CriticalSection 是一个简单对象,为您处理临界区的开销,并让您专注于实际代码。

use PetrKnap\CriticalSection\CriticalSection;
use Symfony\Component\Lock\NoLock;

$lock = new NoLock();

$criticalOutput = CriticalSection::withLock($lock)(fn () => 'This was critical.');

var_dump($criticalOutput);

您可以通过 the WrappingCriticalSection 将临界区一层层包裹起来。这使得结合多个锁变得容易,例如。

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);

您还可以将锁作为数组传递,将组合留给临界区。

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);

您需要只接受已锁定的资源吗?

如果您需要确保您不在临界区外处理资源,请使用 the LockedResource

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));

您的临界区与数据库兼容吗?

使用 the doctrine/dbal 及其 transactional 方法。

/** @var PetrKnap\CriticalSection\CriticalSectionInterface $criticalSection */
/** @var Doctrine\DBAL\Connection $connection */
$criticalSection(
    fn () => $connection->transactional(
        fn () => 'This was critical on DB server.'
    )
);

始终在临界区内使用 transactional 以防止饥饿。

运行 composer require petrknap/critical-section 来安装它。您可以通过 捐赠 支持此项目。该项目根据 the terms of the LGPL-3.0-or-later 许可。