public static function acquire($key)
{
$oldLock = null;
while (true) {
$condition = [
'key' => $key,
'$or' => [[
'expireAt' => null,
],[
'expireAt' => ['$lt' => new \MongoDate()]
]]
];
$update = [
'$setOnInsert' => [
'key' => $key,
],
'$set' => [
'locked' => true,
'expireAt' => new \MongoDate(time() + self::EXPIRE_TIME)
]
];
try {
$oldLock = static::findAndModify($condition, $update, ['upsert' => true]);
break;
} catch (yii\mongodb\Exception $e) {
sleep(self::ACQUIRE_LOCK_INTERVAL);
continue;
}
}
if (!empty($oldLock)) {
if (!empty($oldLock['expireAt'])) {
LogHelper::warning(__METHOD__, 'lock timeout', ['key' => $key]);
while ($oldLock['locked']) {
sleep(self::ACQUIRE_LOCK_INTERVAL);
$oldLock = static::findAndModify(['key' => $key], $update);
}
}
}
}
public static function release($key)
{
$condition = ['key' => $key, 'locked' => true];
$update = ['$set' => ['locked' => false, 'expireAt' => null]];
static::findAndModify($condition, $update);
}