Last active
January 24, 2019 05:49
-
-
Save mikedfunk/870f08a904a8da3f6c55493a9fe8d478 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php declare(strict_types=1); | |
namespace MyApp\Adapter\Repository\Couchbase; | |
use MyApp\Exception\DocumentIsLockedException; | |
class LockHandler | |
{ | |
// ... | |
/** | |
* Wait for a lock to be released, acquire a lock, and return lock data. | |
* | |
* @throws \MyApp\Exception\DocumentIsLockedException if we waited too | |
* long and the lock has still not been released | |
* | |
* @param callable $attemptToAcquireLock This is passed in as a callable so | |
* the LockHandler can remain generic and not have to know how to try to | |
* obtain a lock. You just pass in a method that returns lock data or | |
* falsey and this handles the waiting, tracking, exceptions, and logging. | |
* | |
* @return array whatever the $attemptToAcquireLock callable returns | |
*/ | |
public function waitAndAcquire( | |
string $docKey, | |
callable $attemptToAcquireLock | |
): array { | |
$currentAttempt = 1; | |
// loop until we reach max number of attemps | |
$maxLockCheckAttempts = $this->config['max_lock_check_attempts']; | |
while ($currentAttempt != $maxLockCheckAttempts) { | |
if ($currentAttempt == 10) { | |
Log::warning("Unusually long lock of doc keys: {$docKey}"); | |
} | |
$lock = $attemptToAcquireLock( | |
$docKey, | |
$this->config['max_lock_time_in_seconds'] | |
); | |
if ($lock) { | |
$this->lockTracker->track($docKey, $lock); | |
return $lock; | |
} | |
// keep retrying to access lock key if doc is locked | |
$currentAttempt++; | |
\usleep($this->config['sleep_time_in_microseconds']); | |
} | |
$message = "Document {$docKey} is locked for too long!"; | |
throw new DocumentIsLockedException($message); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment