warmans/dlock

此包最新版本(0.0.3)没有可用的许可证信息。

分布式锁库

0.0.3 2014-05-11 19:45 UTC

This package is not auto-updated.

Last update: 2024-09-28 16:03:07 UTC


README

Build Status Scrutinizer Code Quality Code Coverage

PHP的分布式锁库。此库允许使用缓存服务器(Redis或Memcache)在多个服务器上锁定进程。

示例用例是您有一个必须发生的进程,例如每小时一次,但不能重复,例如导入。在这种情况下,您可以将导入作业设置在所有应用程序服务器上,但每小时只有一个(系统时钟最快的那个)能够获取锁,所以其他所有都会失败。如果任何服务器离线,另一个将获取锁,导入将像往常一样继续。

像大多数分布式系统一样,应保持服务器系统时钟的一致性。如果服务器的时钟比运行作业的时间更不一致,您可能仍然会重复作业。为了避免这种情况,您可以在某处存储作业的全局唯一标识符(例如,在redis集合中),并在锁定后简单地检查作业是否已经被执行(注意:不是在锁定之前,否则您会有竞争条件)。

使用原子函数实现锁定,以避免竞争条件。为了阻止用户创建自己的竞争条件,没有“isLocked”功能。您必须始终尝试创建锁以确定锁定状态。

用法

允许锁通过locked()方法自动处理锁定/解锁

//raw memcache connection
$memcache = new \Memcache();
$memcache->connect('localhost');

//datastore adapter
$adapter = new \Dlock\Datastore\Memcache($memcache);

$lock = new \Dlock\Lock($adapter);
$lock->locked(function(){
    //do something
});

或者自己管理

//raw memcache connection
$memcache = new \Memcache();
$memcache->connect('localhost');

//datastore adapter
$adapter = new \Dlock\Datastore\Memcache($memcache);

$lock = new \Dlock\Lock($adapter);
if ($lock->acquire()) {
    //do something
    $lock->release();
} else {
   //handle lock failure
}

最后,如果您想等待锁可用,可以使用阻塞锁

//raw memcache connection
$memcache = new \Memcache();
$memcache->connect('localhost');

//datastore adapter
$adapter = new \Dlock\Datastore\Memcache($memcache);

$lock = new \Dlock\Lock($adapter);

//wait for up to 30 seconds for lock then return false
if ($lock->acquire(30)) {
    //do something
    $lock->release();
} else {
   //handle lock failure
}

//or use closure with 30 second block
$lock->locked(function(){
    //do something
}, 30);

选项

$lock = new Lock([...], [...], $options);

锁的构造函数的第三个可选参数是一个选项数组。选项如下

适配器

任何实现了DatastoreInterface接口的类都可以用作适配器

interface DatastoreInterface
{
    public function acquireLock($lockId);
    public function releaseLock($lockId);
}

包含的实现如下

Memcache

//raw memcache connection
$memcache = new \Memcache();
$memcache->connect('localhost');

//configure adapter with localhost connction and an hour TTL on locks
$adapter = new \Dlock\Datastore\Memcache($memcache, 3600);

Redis

//raw redis connection
$redis = new \Redis();
$redis->connect('localhost');

//configure adapter with localhost connction and an hour TTL on locks
$adapter = new \Dlock\Datastore\Redis($memcache, 3600);

运行测试

测试分为两个测试用例;单元和集成。集成测试需要在您的localhost上运行运行的Redis和Memcache服务器。

从根目录运行所有测试

phpunit

仅运行单元测试

phpunit --testsuite=unit

仅运行集成测试

phpunit --testsuite=integration