PHP 7.2 버전용으로 올림!
This commit is contained in:
Vendored
+6
-26
@@ -22,12 +22,9 @@ final class Key
|
||||
private $expiringTime;
|
||||
private $state = array();
|
||||
|
||||
/**
|
||||
* @param string $resource
|
||||
*/
|
||||
public function __construct($resource)
|
||||
public function __construct(string $resource)
|
||||
{
|
||||
$this->resource = (string) $resource;
|
||||
$this->resource = $resource;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
@@ -35,39 +32,22 @@ final class Key
|
||||
return $this->resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $stateKey
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasState($stateKey)
|
||||
public function hasState(string $stateKey): bool
|
||||
{
|
||||
return isset($this->state[$stateKey]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $stateKey
|
||||
* @param mixed $state
|
||||
*/
|
||||
public function setState($stateKey, $state)
|
||||
public function setState(string $stateKey, $state): void
|
||||
{
|
||||
$this->state[$stateKey] = $state;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $stateKey
|
||||
*/
|
||||
public function removeState($stateKey)
|
||||
public function removeState(string $stateKey): void
|
||||
{
|
||||
unset($this->state[$stateKey]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $stateKey
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getState($stateKey)
|
||||
public function getState(string $stateKey)
|
||||
{
|
||||
return $this->state[$stateKey];
|
||||
}
|
||||
|
||||
Vendored
+11
-10
@@ -41,12 +41,12 @@ final class Lock implements LockInterface, LoggerAwareInterface
|
||||
* @param float|null $ttl Maximum expected lock duration in seconds
|
||||
* @param bool $autoRelease Whether to automatically release the lock or not when the lock instance is destroyed
|
||||
*/
|
||||
public function __construct(Key $key, StoreInterface $store, $ttl = null, $autoRelease = true)
|
||||
public function __construct(Key $key, StoreInterface $store, float $ttl = null, bool $autoRelease = true)
|
||||
{
|
||||
$this->store = $store;
|
||||
$this->key = $key;
|
||||
$this->ttl = $ttl;
|
||||
$this->autoRelease = (bool) $autoRelease;
|
||||
$this->autoRelease = $autoRelease;
|
||||
|
||||
$this->logger = new NullLogger();
|
||||
}
|
||||
@@ -105,22 +105,25 @@ final class Lock implements LockInterface, LoggerAwareInterface
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function refresh()
|
||||
public function refresh($ttl = null)
|
||||
{
|
||||
if (!$this->ttl) {
|
||||
if (null === $ttl) {
|
||||
$ttl = $this->ttl;
|
||||
}
|
||||
if (!$ttl) {
|
||||
throw new InvalidArgumentException('You have to define an expiration duration.');
|
||||
}
|
||||
|
||||
try {
|
||||
$this->key->resetLifetime();
|
||||
$this->store->putOffExpiration($this->key, $this->ttl);
|
||||
$this->store->putOffExpiration($this->key, $ttl);
|
||||
$this->dirty = true;
|
||||
|
||||
if ($this->key->isExpired()) {
|
||||
throw new LockExpiredException(sprintf('Failed to put off the expiration of the "%s" lock within the specified time.', $this->key));
|
||||
}
|
||||
|
||||
$this->logger->info('Expiration defined for "{resource}" lock for "{ttl}" seconds.', array('resource' => $this->key, 'ttl' => $this->ttl));
|
||||
$this->logger->info('Expiration defined for "{resource}" lock for "{ttl}" seconds.', array('resource' => $this->key, 'ttl' => $ttl));
|
||||
} catch (LockConflictedException $e) {
|
||||
$this->dirty = false;
|
||||
$this->logger->notice('Failed to define an expiration for the "{resource}" lock, someone else acquired the lock.', array('resource' => $this->key));
|
||||
@@ -154,7 +157,7 @@ final class Lock implements LockInterface, LoggerAwareInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isExpired()
|
||||
{
|
||||
@@ -162,9 +165,7 @@ final class Lock implements LockInterface, LoggerAwareInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the remaining lifetime.
|
||||
*
|
||||
* @return float|null Remaining lifetime in seconds. Null when the lock won't expire.
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getRemainingLifetime()
|
||||
{
|
||||
|
||||
+16
-2
@@ -24,7 +24,7 @@ interface LockInterface
|
||||
{
|
||||
/**
|
||||
* Acquires the lock. If the lock is acquired by someone else, the parameter `blocking` determines whether or not
|
||||
* the the call should block until the release of the lock.
|
||||
* the call should block until the release of the lock.
|
||||
*
|
||||
* @param bool $blocking Whether or not the Lock should wait for the release of someone else
|
||||
*
|
||||
@@ -38,10 +38,12 @@ interface LockInterface
|
||||
/**
|
||||
* Increase the duration of an acquired lock.
|
||||
*
|
||||
* @param float|null $ttl Maximum expected lock duration in seconds
|
||||
*
|
||||
* @throws LockConflictedException If the lock is acquired by someone else
|
||||
* @throws LockAcquiringException If the lock can not be refreshed
|
||||
*/
|
||||
public function refresh();
|
||||
public function refresh(/* $ttl = null */);
|
||||
|
||||
/**
|
||||
* Returns whether or not the lock is acquired.
|
||||
@@ -56,4 +58,16 @@ interface LockInterface
|
||||
* @throws LockReleasingException If the lock can not be released
|
||||
*/
|
||||
public function release();
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isExpired();
|
||||
|
||||
/**
|
||||
* Returns the remaining lifetime.
|
||||
*
|
||||
* @return float|null Remaining lifetime in seconds. Null when the lock won't expire.
|
||||
*/
|
||||
public function getRemainingLifetime();
|
||||
}
|
||||
|
||||
+3
-5
@@ -36,7 +36,7 @@ class FlockStore implements StoreInterface
|
||||
*
|
||||
* @throws LockStorageException If the lock directory doesn’t exist or is not writable
|
||||
*/
|
||||
public function __construct($lockPath = null)
|
||||
public function __construct(string $lockPath = null)
|
||||
{
|
||||
if (null === $lockPath) {
|
||||
$lockPath = sys_get_temp_dir();
|
||||
@@ -78,8 +78,7 @@ class FlockStore implements StoreInterface
|
||||
);
|
||||
|
||||
// Silence error reporting
|
||||
set_error_handler(function () {
|
||||
});
|
||||
set_error_handler(function ($type, $msg) use (&$error) { $error = $msg; });
|
||||
if (!$handle = fopen($fileName, 'r')) {
|
||||
if ($handle = fopen($fileName, 'x')) {
|
||||
chmod($fileName, 0444);
|
||||
@@ -91,8 +90,7 @@ class FlockStore implements StoreInterface
|
||||
restore_error_handler();
|
||||
|
||||
if (!$handle) {
|
||||
$error = error_get_last();
|
||||
throw new LockStorageException($error['message'], 0, null);
|
||||
throw new LockStorageException($error, 0, null);
|
||||
}
|
||||
|
||||
// On Windows, even if PHP doc says the contrary, LOCK_NB works, see
|
||||
|
||||
+2
-6
@@ -38,7 +38,7 @@ class MemcachedStore implements StoreInterface
|
||||
* @param \Memcached $memcached
|
||||
* @param int $initialTtl the expiration delay of locks in seconds
|
||||
*/
|
||||
public function __construct(\Memcached $memcached, $initialTtl = 300)
|
||||
public function __construct(\Memcached $memcached, int $initialTtl = 300)
|
||||
{
|
||||
if (!static::isSupported()) {
|
||||
throw new InvalidArgumentException('Memcached extension is required');
|
||||
@@ -149,12 +149,8 @@ class MemcachedStore implements StoreInterface
|
||||
|
||||
/**
|
||||
* Retrieve an unique token for the given key.
|
||||
*
|
||||
* @param Key $key
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getToken(Key $key)
|
||||
private function getToken(Key $key): string
|
||||
{
|
||||
if (!$key->hasState(__CLASS__)) {
|
||||
$token = base64_encode(random_bytes(32));
|
||||
|
||||
+3
-11
@@ -32,7 +32,7 @@ class RedisStore implements StoreInterface
|
||||
* @param \Redis|\RedisArray|\RedisCluster|\Predis\Client $redisClient
|
||||
* @param float $initialTtl the expiration delay of locks in seconds
|
||||
*/
|
||||
public function __construct($redisClient, $initialTtl = 300.0)
|
||||
public function __construct($redisClient, float $initialTtl = 300.0)
|
||||
{
|
||||
if (!$redisClient instanceof \Redis && !$redisClient instanceof \RedisArray && !$redisClient instanceof \RedisCluster && !$redisClient instanceof \Predis\Client && !$redisClient instanceof RedisProxy) {
|
||||
throw new InvalidArgumentException(sprintf('%s() expects parameter 1 to be Redis, RedisArray, RedisCluster or Predis\Client, %s given', __METHOD__, is_object($redisClient) ? get_class($redisClient) : gettype($redisClient)));
|
||||
@@ -124,13 +124,9 @@ class RedisStore implements StoreInterface
|
||||
/**
|
||||
* Evaluates a script in the corresponding redis client.
|
||||
*
|
||||
* @param string $script
|
||||
* @param string $resource
|
||||
* @param array $args
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function evaluate($script, $resource, array $args)
|
||||
private function evaluate(string $script, string $resource, array $args)
|
||||
{
|
||||
if ($this->redis instanceof \Redis || $this->redis instanceof \RedisCluster || $this->redis instanceof RedisProxy) {
|
||||
return $this->redis->eval($script, array_merge(array($resource), $args), 1);
|
||||
@@ -149,12 +145,8 @@ class RedisStore implements StoreInterface
|
||||
|
||||
/**
|
||||
* Retrieves an unique token for the given key.
|
||||
*
|
||||
* @param Key $key
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getToken(Key $key)
|
||||
private function getToken(Key $key): string
|
||||
{
|
||||
if (!$key->hasState(__CLASS__)) {
|
||||
$token = base64_encode(random_bytes(32));
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ class RetryTillSaveStore implements StoreInterface, LoggerAwareInterface
|
||||
* @param int $retrySleep Duration in ms between 2 retry
|
||||
* @param int $retryCount Maximum amount of retry
|
||||
*/
|
||||
public function __construct(StoreInterface $decorated, $retrySleep = 100, $retryCount = PHP_INT_MAX)
|
||||
public function __construct(StoreInterface $decorated, int $retrySleep = 100, int $retryCount = PHP_INT_MAX)
|
||||
{
|
||||
$this->decorated = $decorated;
|
||||
$this->retrySleep = $retrySleep;
|
||||
|
||||
+3
-23
@@ -13,7 +13,6 @@ namespace Symfony\Component\Lock\Store;
|
||||
|
||||
use Symfony\Component\Lock\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Lock\Exception\LockConflictedException;
|
||||
use Symfony\Component\Lock\Exception\NotSupportedException;
|
||||
use Symfony\Component\Lock\Key;
|
||||
use Symfony\Component\Lock\StoreInterface;
|
||||
|
||||
@@ -27,23 +26,13 @@ class SemaphoreStore implements StoreInterface
|
||||
/**
|
||||
* Returns whether or not the store is supported.
|
||||
*
|
||||
* @param bool|null $blocking when not null, checked again the blocking mode
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public static function isSupported($blocking = null)
|
||||
public static function isSupported()
|
||||
{
|
||||
if (!extension_loaded('sysvsem')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (false === $blocking && \PHP_VERSION_ID < 50601) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return extension_loaded('sysvsem');
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
@@ -76,16 +65,7 @@ class SemaphoreStore implements StoreInterface
|
||||
}
|
||||
|
||||
$resource = sem_get(crc32($key));
|
||||
|
||||
if (\PHP_VERSION_ID < 50601) {
|
||||
if (!$blocking) {
|
||||
throw new NotSupportedException(sprintf('The store "%s" does not supports non blocking locks.', get_class($this)));
|
||||
}
|
||||
|
||||
$acquired = sem_acquire($resource);
|
||||
} else {
|
||||
$acquired = sem_acquire($resource, !$blocking);
|
||||
}
|
||||
$acquired = sem_acquire($resource, !$blocking);
|
||||
|
||||
if (!$acquired) {
|
||||
throw new LockConflictedException();
|
||||
|
||||
+14
@@ -97,6 +97,20 @@ class LockTest extends TestCase
|
||||
$lock->refresh();
|
||||
}
|
||||
|
||||
public function testRefreshCustom()
|
||||
{
|
||||
$key = new Key(uniqid(__METHOD__, true));
|
||||
$store = $this->getMockBuilder(StoreInterface::class)->getMock();
|
||||
$lock = new Lock($key, $store, 10);
|
||||
|
||||
$store
|
||||
->expects($this->once())
|
||||
->method('putOffExpiration')
|
||||
->with($key, 20);
|
||||
|
||||
$lock->refresh(20);
|
||||
}
|
||||
|
||||
public function testIsAquired()
|
||||
{
|
||||
$key = new Key(uniqid(__METHOD__, true));
|
||||
|
||||
@@ -31,6 +31,7 @@ trait BlockingStoreTestTrait
|
||||
* This test is time sensible: the $clockDelay could be adjust.
|
||||
*
|
||||
* @requires extension pcntl
|
||||
* @requires extension posix
|
||||
* @requires function pcntl_sigwaitinfo
|
||||
*/
|
||||
public function testBlockingLocks()
|
||||
@@ -38,12 +39,6 @@ trait BlockingStoreTestTrait
|
||||
// Amount a microsecond used to order async actions
|
||||
$clockDelay = 50000;
|
||||
|
||||
if (\PHP_VERSION_ID < 50600 || defined('HHVM_VERSION_ID')) {
|
||||
$this->markTestSkipped('The PHP engine does not keep resource in child forks');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var StoreInterface $store */
|
||||
$store = $this->getStore();
|
||||
$key = new Key(uniqid(__METHOD__, true));
|
||||
|
||||
@@ -27,10 +27,6 @@ class SemaphoreStoreTest extends AbstractStoreTest
|
||||
*/
|
||||
protected function getStore()
|
||||
{
|
||||
if (\PHP_VERSION_ID < 50601) {
|
||||
$this->markTestSkipped('Non blocking semaphore are supported by PHP version greater or equals than 5.6.1');
|
||||
}
|
||||
|
||||
return new SemaphoreStore();
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+2
-3
@@ -16,8 +16,7 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^5.5.9|>=7.0.8",
|
||||
"symfony/polyfill-php70": "~1.0",
|
||||
"php": "^7.1.3",
|
||||
"psr/log": "~1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
@@ -32,7 +31,7 @@
|
||||
"minimum-stability": "dev",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.4-dev"
|
||||
"dev-master": "4.1-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user