2024-05-07 12:17:25 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace Illuminate\Cache;
|
|
|
|
|
|
|
|
|
|
use Illuminate\Contracts\Cache\Lock as LockContract;
|
|
|
|
|
use Illuminate\Contracts\Cache\LockTimeoutException;
|
|
|
|
|
use Illuminate\Support\InteractsWithTime;
|
|
|
|
|
use Illuminate\Support\Str;
|
|
|
|
|
|
|
|
|
|
abstract class Lock implements LockContract
|
|
|
|
|
{
|
|
|
|
|
use InteractsWithTime;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The name of the lock.
|
|
|
|
|
*
|
|
|
|
|
* @var string
|
|
|
|
|
*/
|
|
|
|
|
protected $name;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The number of seconds the lock should be maintained.
|
|
|
|
|
*
|
|
|
|
|
* @var int
|
|
|
|
|
*/
|
|
|
|
|
protected $seconds;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The scope identifier of this lock.
|
|
|
|
|
*
|
|
|
|
|
* @var string
|
|
|
|
|
*/
|
|
|
|
|
protected $owner;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The number of milliseconds to wait before re-attempting to acquire a lock while blocking.
|
|
|
|
|
*
|
|
|
|
|
* @var int
|
|
|
|
|
*/
|
|
|
|
|
protected $sleepMilliseconds = 250;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Create a new lock instance.
|
|
|
|
|
*
|
|
|
|
|
* @param string $name
|
|
|
|
|
* @param int $seconds
|
|
|
|
|
* @param string|null $owner
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
|
|
|
|
public function __construct($name, $seconds, $owner = null)
|
|
|
|
|
{
|
|
|
|
|
if (is_null($owner)) {
|
|
|
|
|
$owner = Str::random();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$this->name = $name;
|
|
|
|
|
$this->owner = $owner;
|
|
|
|
|
$this->seconds = $seconds;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Attempt to acquire the lock.
|
|
|
|
|
*
|
|
|
|
|
* @return bool
|
|
|
|
|
*/
|
|
|
|
|
abstract public function acquire();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Release the lock.
|
|
|
|
|
*
|
|
|
|
|
* @return bool
|
|
|
|
|
*/
|
|
|
|
|
abstract public function release();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns the owner value written into the driver for this lock.
|
|
|
|
|
*
|
|
|
|
|
* @return string
|
|
|
|
|
*/
|
|
|
|
|
abstract protected function getCurrentOwner();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Attempt to acquire the lock.
|
|
|
|
|
*
|
|
|
|
|
* @param callable|null $callback
|
|
|
|
|
* @return mixed
|
|
|
|
|
*/
|
|
|
|
|
public function get($callback = null)
|
|
|
|
|
{
|
|
|
|
|
$result = $this->acquire();
|
|
|
|
|
|
|
|
|
|
if ($result && is_callable($callback)) {
|
|
|
|
|
try {
|
|
|
|
|
return $callback();
|
|
|
|
|
} finally {
|
|
|
|
|
$this->release();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Attempt to acquire the lock for the given number of seconds.
|
|
|
|
|
*
|
|
|
|
|
* @param int $seconds
|
|
|
|
|
* @param callable|null $callback
|
2024-08-13 13:44:16 +00:00
|
|
|
* @return mixed
|
2024-05-07 12:17:25 +02:00
|
|
|
*
|
|
|
|
|
* @throws \Illuminate\Contracts\Cache\LockTimeoutException
|
|
|
|
|
*/
|
|
|
|
|
public function block($seconds, $callback = null)
|
|
|
|
|
{
|
|
|
|
|
$starting = $this->currentTime();
|
|
|
|
|
|
|
|
|
|
while (! $this->acquire()) {
|
|
|
|
|
usleep($this->sleepMilliseconds * 1000);
|
|
|
|
|
|
|
|
|
|
if ($this->currentTime() - $seconds >= $starting) {
|
|
|
|
|
throw new LockTimeoutException;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (is_callable($callback)) {
|
|
|
|
|
try {
|
|
|
|
|
return $callback();
|
|
|
|
|
} finally {
|
|
|
|
|
$this->release();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns the current owner of the lock.
|
|
|
|
|
*
|
|
|
|
|
* @return string
|
|
|
|
|
*/
|
|
|
|
|
public function owner()
|
|
|
|
|
{
|
|
|
|
|
return $this->owner;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Determines whether this lock is allowed to release the lock in the driver.
|
|
|
|
|
*
|
|
|
|
|
* @return bool
|
|
|
|
|
*/
|
|
|
|
|
protected function isOwnedByCurrentProcess()
|
|
|
|
|
{
|
|
|
|
|
return $this->getCurrentOwner() === $this->owner;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2024-08-13 13:44:16 +00:00
|
|
|
* Specify the number of milliseconds to sleep in between blocked lock acquisition attempts.
|
2024-05-07 12:17:25 +02:00
|
|
|
*
|
|
|
|
|
* @param int $milliseconds
|
|
|
|
|
* @return $this
|
|
|
|
|
*/
|
|
|
|
|
public function betweenBlockedAttemptsSleepFor($milliseconds)
|
|
|
|
|
{
|
|
|
|
|
$this->sleepMilliseconds = $milliseconds;
|
|
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
}
|