This commit is contained in:
Fabien Potencier 2019-12-11 01:47:24 +01:00
parent e8ecfe3535
commit 93f430b94f
3 changed files with 21 additions and 22 deletions

View File

@ -1,18 +1,22 @@
CHANGELOG CHANGELOG
========= =========
5.1.0
-----
* added the MongoDbStore supporting MongoDB servers >=2.2
5.0.0 5.0.0
----- -----
* `Factory` has been removed, use `LockFactory` instead. * `Factory` has been removed, use `LockFactory` instead.
* `StoreInterface` has been removed, use `BlockingStoreInterface` and `PersistingStoreInterface` instead. * `StoreInterface` has been removed, use `BlockingStoreInterface` and `PersistingStoreInterface` instead.
* removed the `waitAndSave()` method from `CombinedStore`, `MemcachedStore`, `RedisStore`, and `ZookeeperStore` * removed the `waitAndSave()` method from `CombinedStore`, `MemcachedStore`, `RedisStore`, and `ZookeeperStore`
4.4.0 4.4.0
----- -----
* added InvalidTtlException * added InvalidTtlException
* added the MongoDbStore supporting MongoDB servers >=2.2
* deprecated `StoreInterface` in favor of `BlockingStoreInterface` and `PersistingStoreInterface` * deprecated `StoreInterface` in favor of `BlockingStoreInterface` and `PersistingStoreInterface`
* `Factory` is deprecated, use `LockFactory` instead * `Factory` is deprecated, use `LockFactory` instead
* `StoreFactory::createStore` allows PDO and Zookeeper DSN. * `StoreFactory::createStore` allows PDO and Zookeeper DSN.

View File

@ -44,8 +44,6 @@ use Symfony\Component\Lock\StoreInterface;
* *
* @see https://docs.mongodb.com/manual/reference/limits/#Index-Key-Limit * @see https://docs.mongodb.com/manual/reference/limits/#Index-Key-Limit
* *
* @requires extension mongodb
*
* @author Joe Bennett <joe@assimtech.com> * @author Joe Bennett <joe@assimtech.com>
*/ */
class MongoDbStore implements StoreInterface class MongoDbStore implements StoreInterface
@ -109,10 +107,10 @@ class MongoDbStore implements StoreInterface
$this->collection = $mongo; $this->collection = $mongo;
} elseif ($mongo instanceof Client) { } elseif ($mongo instanceof Client) {
if (null === $this->options['database']) { if (null === $this->options['database']) {
throw new InvalidArgumentException(sprintf('%s() requires the "database" option when constructing with a %s', __METHOD__, Client::class)); throw new InvalidArgumentException(sprintf('"%s()" requires the "database" option when constructing with a "%s".', __METHOD__, Client::class));
} }
if (null === $this->options['collection']) { if (null === $this->options['collection']) {
throw new InvalidArgumentException(sprintf('%s() requires the "collection" option when constructing with a %s', __METHOD__, Client::class)); throw new InvalidArgumentException(sprintf('"%s()" requires the "collection" option when constructing with a "%s".', __METHOD__, Client::class));
} }
$this->client = $mongo; $this->client = $mongo;
@ -127,28 +125,28 @@ class MongoDbStore implements StoreInterface
$this->options['collection'] = $this->options['collection'] ?? $query['collection'] ?? null; $this->options['collection'] = $this->options['collection'] ?? $query['collection'] ?? null;
$this->options['database'] = $this->options['database'] ?? ltrim($parsedUrl['path'] ?? '', '/') ?: null; $this->options['database'] = $this->options['database'] ?? ltrim($parsedUrl['path'] ?? '', '/') ?: null;
if (null === $this->options['database']) { if (null === $this->options['database']) {
throw new InvalidArgumentException(sprintf('%s() requires the "database" in the uri path or option when constructing with a uri', __METHOD__)); throw new InvalidArgumentException(sprintf('"%s()" requires the "database" in the URI path or option when constructing with a URI.', __METHOD__));
} }
if (null === $this->options['collection']) { if (null === $this->options['collection']) {
throw new InvalidArgumentException(sprintf('%s() requires the "collection" in the uri querystring or option when constructing with a uri', __METHOD__)); throw new InvalidArgumentException(sprintf('"%s()" requires the "collection" in the URI querystring or option when constructing with a URI.', __METHOD__));
} }
$this->uri = $mongo; $this->uri = $mongo;
} else { } else {
throw new InvalidArgumentException(sprintf('%s() requires %s or %s or URI as first argument, %s given.', __METHOD__, Collection::class, Client::class, \is_object($mongo) ? \get_class($mongo) : \gettype($mongo))); throw new InvalidArgumentException(sprintf('"%s()" requires "%s" or "%s" or URI as first argument, "%s" given.', __METHOD__, Collection::class, Client::class, \is_object($mongo) ? \get_class($mongo) : \gettype($mongo)));
} }
if ($this->options['gcProbablity'] < 0.0 || $this->options['gcProbablity'] > 1.0) { if ($this->options['gcProbablity'] < 0.0 || $this->options['gcProbablity'] > 1.0) {
throw new InvalidArgumentException(sprintf('%s() gcProbablity must be a float from 0.0 to 1.0, %f given.', __METHOD__, $this->options['gcProbablity'])); throw new InvalidArgumentException(sprintf('"%s()" gcProbablity must be a float from 0.0 to 1.0, "%f" given.', __METHOD__, $this->options['gcProbablity']));
} }
if ($this->initialTtl <= 0) { if ($this->initialTtl <= 0) {
throw new InvalidTtlException(sprintf('%s() expects a strictly positive TTL. Got %d.', __METHOD__, $this->initialTtl)); throw new InvalidTtlException(sprintf('"%s()" expects a strictly positive TTL, got "%d".', __METHOD__, $this->initialTtl));
} }
} }
/** /**
* Create a TTL index to automatically remove expired locks. * Creates a TTL index to automatically remove expired locks.
* *
* If the gcProbablity option is set higher than 0.0 (defaults to 0.001); * If the gcProbablity option is set higher than 0.0 (defaults to 0.001);
* there is a chance this will be called on self::save(). * there is a chance this will be called on self::save().
@ -205,12 +203,7 @@ class MongoDbStore implements StoreInterface
throw new LockAcquiringException('Failed to acquire lock', 0, $e); throw new LockAcquiringException('Failed to acquire lock', 0, $e);
} }
if ($this->options['gcProbablity'] > 0.0 if ($this->options['gcProbablity'] > 0.0 && (1.0 === $this->options['gcProbablity'] || (random_int(0, PHP_INT_MAX) / PHP_INT_MAX) <= $this->options['gcProbablity'])) {
&& (
1.0 === $this->options['gcProbablity']
|| (random_int(0, PHP_INT_MAX) / PHP_INT_MAX) <= $this->options['gcProbablity']
)
) {
$this->createTtlIndex(); $this->createTtlIndex();
} }

View File

@ -12,6 +12,8 @@
namespace Symfony\Component\Lock\Tests\Store; namespace Symfony\Component\Lock\Tests\Store;
use MongoDB\Client; use MongoDB\Client;
use Symfony\Component\Lock\Exception\InvalidArgumentException;
use Symfony\Component\Lock\Exception\NotSupportedException;
use Symfony\Component\Lock\Key; use Symfony\Component\Lock\Key;
use Symfony\Component\Lock\PersistingStoreInterface; use Symfony\Component\Lock\PersistingStoreInterface;
use Symfony\Component\Lock\Store\MongoDbStore; use Symfony\Component\Lock\Store\MongoDbStore;
@ -70,7 +72,7 @@ class MongoDbStoreTest extends AbstractStoreTest
public function testNonBlocking() public function testNonBlocking()
{ {
$this->expectException(\Symfony\Component\Lock\Exception\NotSupportedException::class); $this->expectException(NotSupportedException::class);
$store = $this->getStore(); $store = $this->getStore();
@ -113,7 +115,7 @@ class MongoDbStoreTest extends AbstractStoreTest
*/ */
public function testInvalidConstructionMethods($mongo, array $options) public function testInvalidConstructionMethods($mongo, array $options)
{ {
$this->expectException('Symfony\Component\Lock\Exception\InvalidArgumentException'); $this->expectException(InvalidArgumentException::class);
new MongoDbStore($mongo, $options); new MongoDbStore($mongo, $options);
} }