@@ -220,6 +220,7 @@ Store Scope Blocking Expiring
220220============================================ ====== ======== ========
221221:ref: `FlockStore <lock-store-flock >` local yes no
222222:ref: `MemcachedStore <lock-store-memcached >` remote no yes
223+ :ref: `MongoDbStore <lock-store-mongodb >` remote no yes
223224:ref: `PdoStore <lock-store-pdo >` remote no yes
224225:ref: `RedisStore <lock-store-redis >` remote no yes
225226:ref: `SemaphoreStore <lock-store-semaphore >` local yes no
@@ -269,6 +270,68 @@ support blocking, and expects a TTL to avoid stalled locks::
269270
270271.. _lock-store-pdo :
271272
273+ .. _lock-store-mongodb :
274+
275+ MongoDbStore
276+ ~~~~~~~~~~~~
277+
278+ .. versionadded :: 5.1
279+
280+ The ``MongoDbStore `` was introduced in Symfony 5.1.
281+
282+ The MongoDbStore saves locks on a MongoDB server ``>=2.2 ``, it requires a
283+ ``\MongoDB\Collection `` or ``\MongoDB\Client `` from `mongodb/mongodb `_ or a
284+ `MongoDB Connection String `_.
285+ This store does not support blocking and expects a TTL to
286+ avoid stalled locks::
287+
288+ use Symfony\Component\Lock\Store\MongoDbStore;
289+
290+ $mongo = 'mongodb://localhost/database?collection=lock';
291+ $options = [
292+ 'gcProbablity' => 0.001,
293+ 'database' => 'myapp',
294+ 'collection' => 'lock',
295+ 'uriOptions' => [],
296+ 'driverOptions' => [],
297+ ];
298+ $store = new MongoDbStore($mongo, $options);
299+
300+ The ``MongoDbStore `` takes the following ``$options `` (depending on the first parameter type):
301+
302+ ============= ================================================================================================
303+ Option Description
304+ ============= ================================================================================================
305+ gcProbablity Should a TTL Index be created expressed as a probability from 0.0 to 1.0 (Defaults to ``0.001 ``)
306+ database The name of the database
307+ collection The name of the collection
308+ uriOptions Array of uri options for `MongoDBClient::__construct `_
309+ driverOptions Array of driver options for `MongoDBClient::__construct `_
310+ ============= ================================================================================================
311+
312+ When the first parameter is a:
313+
314+ ``MongoDB\Collection ``:
315+
316+ - ``$options['database'] `` is ignored
317+ - ``$options['collection'] `` is ignored
318+
319+ ``MongoDB\Client ``:
320+
321+ - ``$options['database'] `` is mandatory
322+ - ``$options['collection'] `` is mandatory
323+
324+ MongoDB Connection String:
325+
326+ - ``$options['database'] `` is used otherwise ``/path `` from the DSN, at least one is mandatory
327+ - ``$options['collection'] `` is used otherwise ``?collection= `` from the DSN, at least one is mandatory
328+
329+ .. note ::
330+
331+ The ``collection `` querystring parameter is not part of the `MongoDB Connection String `_ definition.
332+ It is used to allow constructing a ``MongoDbStore `` using a `Data Source Name (DSN) `_ without ``$options ``.
333+
334+
272335PdoStore
273336~~~~~~~~
274337
@@ -403,6 +466,7 @@ Remote Stores
403466~~~~~~~~~~~~~
404467
405468Remote stores (:ref: `MemcachedStore <lock-store-memcached >`,
469+ :ref: `MongoDbStore <lock-store-mongodb >`,
406470:ref: `PdoStore <lock-store-pdo >`,
407471:ref: `RedisStore <lock-store-redis >` and
408472:ref: `ZookeeperStore <lock-store-zookeeper >`) use a unique token to recognize
@@ -428,6 +492,7 @@ Expiring Stores
428492~~~~~~~~~~~~~~~
429493
430494Expiring stores (:ref: `MemcachedStore <lock-store-memcached >`,
495+ :ref: `MongoDbStore <lock-store-mongodb >`,
431496:ref: `PdoStore <lock-store-pdo >` and
432497:ref: `RedisStore <lock-store-redis >`)
433498guarantee that the lock is acquired only for the defined duration of time. If
@@ -546,6 +611,46 @@ method uses the Memcached's ``flush()`` method which purges and removes everythi
546611 The method ``flush() `` must not be called, or locks should be stored in a
547612 dedicated Memcached service away from Cache.
548613
614+ MongoDbStore
615+ ~~~~~~~~~~~~
616+
617+ .. caution ::
618+
619+ The locked resource name is indexed in the ``_id `` field of the lock
620+ collection. Beware that in MongoDB an indexed field's value can be
621+ `a maximum of 1024 bytes in length `_ inclusive of structural overhead.
622+
623+ A TTL index must be used to automatically clean up expired locks.
624+ Such an index can be created manually:
625+
626+ .. code-block :: javascript
627+
628+ db .lock .ensureIndex (
629+ { " expires_at" : 1 },
630+ { " expireAfterSeconds" : 0 }
631+ )
632+
633+ Alternatively, the method ``MongoDbStore::createTtlIndex(int $expireAfterSeconds = 0) ``
634+ can be called once to create the TTL index during database setup. Read more
635+ about `Expire Data from Collections by Setting TTL `_ in MongoDB.
636+
637+ .. tip ::
638+
639+ ``MongoDbStore `` will attempt to automatically create a TTL index.
640+ It's recommended to set constructor option ``gcProbablity = 0.0 `` to
641+ disable this behavior if you have manually dealt with TTL index creation.
642+
643+ .. caution ::
644+
645+ This store relies on all PHP application and database nodes to have
646+ synchronized clocks for lock expiry to occur at the correct time. To ensure
647+ locks don't expire prematurely; the lock TTL should be set with enough extra
648+ time in ``expireAfterSeconds `` to account for any clock drift between nodes.
649+
650+ ``writeConcern ``, ``readConcern `` and ``readPreference `` are not specified by
651+ MongoDbStore meaning the collection's settings will take effect. Read more
652+ about `Replica Set Read and Write Semantics `_ in MongoDB.
653+
549654PdoStore
550655~~~~~~~~~~
551656
@@ -672,10 +777,16 @@ instance, during the deployment of a new version. Processes with new
672777configuration must not be started while old processes with old configuration
673778are still running.
674779
780+ .. _`a maximum of 1024 bytes in length` : https://docs.mongodb.com/manual/reference/limits/#Index-Key-Limit
675781.. _`ACID` : https://en.wikipedia.org/wiki/ACID
782+ .. _`Data Source Name (DSN)` : https://en.wikipedia.org/wiki/Data_source_name
783+ .. _`Doctrine DBAL Connection` : https://github.com/doctrine/dbal/blob/master/src/Connection.php
784+ .. _`Expire Data from Collections by Setting TTL` : https://docs.mongodb.com/manual/tutorial/expire-data/
676785.. _`locks` : https://en.wikipedia.org/wiki/Lock_(computer_science)
677- .. _`PHP semaphore functions` : https://www.php.net/manual/en/book.sem.php
786+ .. _`MongoDB Connection String` : https://docs.mongodb.com/manual/reference/connection-string/
787+ .. _`mongodb/mongodb` : https://packagist.org/packages/mongodb/mongodb
788+ .. _`MongoDBClient::__construct` : https://docs.mongodb.com/php-library/current/reference/method/MongoDBClient__construct/
678789.. _`PDO` : https://www.php.net/pdo
679- .. _`Doctrine DBAL Connection ` : https://github.com/doctrine/dbal/blob/master/lib/Doctrine/DBAL/Connection .php
680- .. _`Data Source Name (DSN) ` : https://en.wikipedia.org/wiki/Data_source_name
790+ .. _`PHP semaphore functions ` : https://www.php.net/manual/en/book.sem .php
791+ .. _`Replica Set Read and Write Semantics ` : https://docs.mongodb.com/manual/applications/replication/
681792.. _`ZooKeeper` : https://zookeeper.apache.org/
0 commit comments