amegatron/php-sync

一套接口和通用实现,为后台PHP脚本提供同步可能性

v1.0.0-beta 2020-09-24 21:23 UTC

This package is auto-updated.

Last update: 2024-08-25 08:06:44 UTC


README

此包提供了一套接口和通用实现,这些实现可以简化在并行运行的不同PHP脚本之间的同步。

接口

一般来说,任何消费端都应该依赖于两个接口:LockInterfaceIntegerInterface

LockInterface

LockInterface 的目的是提供一个接口,允许并行进程阻塞或等待彼此或其他情况。考虑以下示例

你有一些在后台运行的脚本(我们称之为 workers),例如,从任何消息队列引擎中获取新的消息(任务),并始终由 supervisor 等辅助程序启动和结束。如果您需要暂时暂停它们,可以在系统中引入一个锁,所有工作者在获取新任务之前都会等待这个锁。一般来说,这可能看起来像这样

  1. 在获取新任务之前,所有工作者都会 等待 一个名为 pause 的锁
// $lock is an instance of LockInterface which is associated with a specific Lock called 'pause'
$lock->wait(); 
// further execution is blocked until the Lock is released
  1. 无论您想从哪里控制这些工作者(例如,从网络管理面板),您只需 获取 同样的锁来暂停工作者
// $lock is an instance of LockInterface which is associated with a specific Lock called 'pause'
$lock->lock();

所有工作者将暂停,等待控制端释放锁

$lock->unlock();

您也可以使用 exists 方法检查是否存在现有的(已获取)锁

if ($lock->exists()) {
    // ...
}

请参阅 通用实现 获取更多信息。

IntegerInterface

IntegerInterface 提供了一个通用的接口,可以从并行脚本中以原子方式处理整数。最常见的一个用例是跟踪后台任务的进度,无论是为了装饰目的(只是为了向用户显示进度),还是为了实现同步这些后台任务的某些不同逻辑。

例如,假设您向队列中放入了 N 个新任务。同时,您也可以引入一个新的整数,例如 progress,它将作为计数器。在完成单个任务后,每个工作者都会 增加 该整数。

// $integers is an instance of IntegerInterface associated with 'progress'  
$integer->increment(1);

每次您需要显示总进度时,只需将 progress 整数与 N(这也可能是另一个 IntegerInterface 实例)一起使用,计算进度百分比并显示出来。您也可以直接与 N 一起工作,每次任务完成时调用 decrement

$integer->decrement(1); // which is also the same as $integer->increment(-1);
if ($integer->getValue() == 0) {
    // ...
}

您始终可以检查一个整数是否存在或 删除

if ($integer->exists()) {
    // ...
    $integer->delete();
}

请参阅 通用实现 获取更多信息。

规范

请参阅 /src/Core 路径下的源代码,以获取有关这些接口的详细规范。

通用实现

此包还提供了上述接口的通用实现。此实现本身并不工作,这意味着它不提供创建原子的锁和整数的任何确切实现。相反,它仅依赖于底层 Drivers 来执行实际工作。

此实现利用 Singleton 模式,以确保在脚本运行过程中,表示相同实体的锁和整数仅由单个对象表示。

假设您想获取一个表示名为 some_lock 的锁的对象。在这种情况下,您会这样做

$driver = // get a specific driver somehow, see further
$lock = \PhpSync\Generic\Lock::getInstance('some_lock', $driver);

稍后,如果您尝试获取同一个 some_lock 的 Lock 实例,您将得到完全相同的实例

$lock2 = \PhpSync\Generic\Lock::getInstance('some_lock', $driver);
// $lock === $lock2

这里的 some_lock 是一个代表单个锁的 key(或 name)。

通过 key 进行单例管理是在 Lock 类内部完成的,但您仍然可以提供自己的 SingletonManagerInterface 作为第三个参数,以防您需要为 Locks 使用某种“命名空间”。您甚至可以在每次调用时提供 new SingletonManager(),如果您出于某种原因根本不需要任何“单例”。

上述内容同样适用于泛型的 Integer 实现。

驱动器

这个泛型实现使用 Drivers 来实现主要功能。具体来说,有两种类型的驱动器:LockSyncDriverInterfaceIntegerSyncDriverInterface,它们提供进行某些原子操作的对应接口。这些驱动器不包括在这个包中,必须额外安装。

例如,可以考虑查看相邻的包 amegatron/php-sync-fs,它提供了基于本地文件系统实现功能的驱动器。