Skip to content
This repository has been archived by the owner on Jan 8, 2020. It is now read-only.

Add MongoDB adapter for Zend\Cache #6078

Closed
wants to merge 10 commits into from
Closed

Add MongoDB adapter for Zend\Cache #6078

wants to merge 10 commits into from

Conversation

alexdenvir
Copy link
Contributor

Adds a MongoDB adapter for Zend\Cache, along with its own Options class.

Usage is the same as any other adapter - just throw an array of config at StorageFactory::factory() and it will handle the rest.

$config = array(
    'adapter' => array(
        'name'    => 'mongodb',
        'options' => array(
            'libOptions' => array(
                'server' => '',
                'database' => '',
                'collection' => '',
                'options' => array(),
                'driverOptions' => array(),
            ),
            'namespaceSeparator' => '',
            'resourceId' => ''
        ),
    ),
);

The libOptions for collection, server and database are required. server will most likely look something like mongodb://localhost. database and collection should be used to define the name of the MongoDB database and collection to use for the cache (Mongo will create these on first use if they do not exist).
libOptions->options is passed to Mongo|MongoClient's __construct as the options parameter - so you can set fsync, write concern, username, password etc here. libOptions->driverOptions is also passed as the third parameter - these are generally used for connection context settings or logging callbacks. See http://www.php.net/manual/en/mongoclient.construct.php for all options

Tests are included following the example of the existing adapter test cases

* @param mixed $options
* @return $this
*/
public function setOptions($options)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this public setter needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically, no. This could get away with using the parents public setter instead. However this would mean the options object would not be an instance of MongoDBOptions.

I could drop the MongoDBOptions altogether, but I'm not a fan of the magic __get and __set functions. However I will go with whatever is required on this

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's fine, didn't know there was a setter in the parent class.

$mongo = new MongoClient($options->getConnectString());
} catch (MongoException $e) {
throw new RuntimeException($e->getMessage(), $e->getCode(), $e);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would be a little leary of trying to instantiate a Mongo connection here. I'm thinking it should be injected. The SessionHandler for Mongo injects an instance and checks that it's Mongo or MongoClient. Unless I'm missing it somewhere, ZF2 can still support older Mongo extensions that do not include MongoClient.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a fair point.
The first problem I can see with injecting Mongo/MongoClient in is that it would not quite work well with StorageFactory::factory without modification - but it can be done I think.

On the same trail of thought, I'm also considering adding https://github.com/mongofill/mongofill as a recommends in composer.json, as this is a pure php implementation that should supposedly work as a drop in replacement for the Mongo extension where the Mongo extension isn't/cannot be installed. If its also added as a require-dev, it allows us to test this code on Travis again (its not currently tested because it completely halts the test run under hhvm - even if hhvm isn't fully supported yet completely breaking it is not something I want to do).

So, I'll take a look at adding some kind of factory for Mongo that will provide an instance of Mongo or MongoClient depending on whats available, and update both this and the SessionHandler to use that. Sound good?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be done on an own MongoDbResourceManager similar to Memcache[d]ResourceManager and RedisResourceManager

@Ocramius Ocramius added Cache and removed enhancement labels Apr 2, 2014
@@ -0,0 +1,85 @@
<?php

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no new blank line after <?php for consistency with other files.

@marc-mabe
Copy link
Member

Great additional feature and most of my notes should be simple do fix 👍

I'm missing changes to composer.json and the method internalGetCapabilities isn't overwritten - please contact me if you need help do define capabilities.

Also I think MongoCollection::drop() could be used to implement FlushableInterface and on creating a new colletion the key should be indexed. That do you think?

… on returned cached items, add MongoID as supported metadata
return $resource['resource'];
}

public function setLibOptions($id, array $libOptions)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This setter looks like not a good idea to as it modifies the internal data structure of the $resource array.
It would be better to define different setter to define each of the possible configurations:

  • setCollectionName
  • setDatabaseName
  • setDriverOptions
  • setConnectionOptions (this will be the second argument of MongoClient - It's named optins in php.net but documented as An array of options for the connection)
  • setServer

@marc-mabe
Copy link
Member

@alexdenvir Please update the resource manager and review/explain return false of simple operations. By default the storage adapter should throw exceptions in cases of an error and only return false in cases of not executed operations (like removing an not existing item)

@marc-mabe
Copy link
Member

@alexdenvir ping - last chance to go into 2.4 I think

*/
public function __construct($options = null)
{
if (!class_exists('\Mongo') || !class_exists('\MongoClient')) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should not prefix with \.

@Ocramius Ocramius self-assigned this Nov 13, 2014
Ocramius added a commit that referenced this pull request Nov 13, 2014
Ocramius added a commit that referenced this pull request Nov 13, 2014
…lementation details, simplifying imports and docblocks
@Ocramius
Copy link
Member

I rebased, merged and cleaned up some CS issues in the PR in d24ef90

Thanks @alexdenvir and @marc-mabe!

@Ocramius Ocramius closed this Nov 13, 2014
gianarb pushed a commit to zendframework/zend-cache that referenced this pull request May 15, 2015
gianarb pushed a commit to zendframework/zend-cache that referenced this pull request May 15, 2015
gianarb pushed a commit to zendframework/zend-cache that referenced this pull request May 15, 2015
gianarb pushed a commit to zendframework/zend-cache that referenced this pull request May 15, 2015
gianarb pushed a commit to zendframework/zend-cache that referenced this pull request May 15, 2015
gianarb pushed a commit to zendframework/zend-cache that referenced this pull request May 15, 2015
…not needed, cleaning up implementation details, simplifying imports and docblocks
gianarb pushed a commit to zendframework/zend-cache that referenced this pull request May 15, 2015
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants