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

Means to statically configure a common *ResourceManager for Memcached/Redis #5787

Closed
icywolfy opened this issue Feb 5, 2014 · 8 comments
Closed

Comments

@icywolfy
Copy link
Contributor

icywolfy commented Feb 5, 2014

Right now, using caches with the built in tools is fairly good, however, when using Redis/Memcached, -every- instance has a private ResourceManager, and thus, creates a new connection per TTL/Namespace. (Obviously defeating the intent of the ResourceManager)

ie: given the configuration:

return array(
  'caches' => array(
    'CacheStorage\MerlinId' => array(
      'adapter' => array(
        'name' => 'redis',
        'options' => array(
          'server' => 'devredis',
          'ttl' => 0,
          'namespace' => 'merlinid',
        ),
      ),
    ),
    'CacheStorage\Trends' => array(
      'adapter' => array(
        'name' => 'redis',
        'options' => array(
          'server' => 'devredis',
          'ttl' => 86400,
          'namespace' => 'trends',
        ),
      ),
    ),
  ),
);

StorageCacheAbstractServiceFactory::createServiceWithName
calls StorageFactory explictly. Thus:

// $requestedName = 'CacheStorage\Trends'
$config = $config[$requestedName];
StorageFactory::factory($config);

Which then calls

StorageFactory::adapterFactory('redis', $options)

Here is where it creates the Redis instance,
but it then calls:

$adapter->setOptions($options);
// Redis::setOptions($options): 
   if (!$options instanceof RedisOptions) {
      $options = new RedisOptions($options);
   }

Which creates a new RedisOptions/MemcachedOptions
Which implicitly uses a new ResourceManager.

Thus, there is no sharing of the connection, and every cache namespace creates a new connection.

At a loss as to how to cleanly create the RedisOptions across the application currently.

???

  • Extend StorageCacheAbstractFactory
  • Override createServiceWithName
  • pre-parse the ['options'] / ['adapter']['options'] for a 'resource_manager' key.
    • if string, $services->get($resourceManager)
  • call StorageFactory::factory($config) with this partially-processed config

???

Also, at a loss as to how to cleanly implement a shared resource manager that can be defined in a configuration file.

Thoughts:

  1. Expose ServiceLocator to RedisOptions/MemcachedOptions and if it's passed in a string, resolve it to an instance.
  2. Update StorageFactory static class to check for these two special cases, and if a string is passed in under the resourceManager key, resolve it to an instance. However, this then requires to explictly set a adapterPluginManager, as get will create a new instance with no concept of a global service locator, nor is there any means to inject new aliases/factories/etc into this pluginManager via static configuration.

Clarification:
Would be nice to have a configuration that looked like:

return array(
  'caches' => array(
    'CacheStorage\MerlinId' => array(
      'adapter' => array(
        'name' => 'redis',
        'options' => array(
          'resource_id' => 'devredis',
          'resource_manager' => 'Zend\Cache\Storage\Adapter\RedisResourceManager',
          'ttl' => 0,
          'namespace' => 'merlinid',
        ),
      ),
    ),
    'CacheStorage\Users' => array(
      'adapter' => array(
        'name' => 'redis',
        'options' => array(
          'resource_id' => 'devredis',
          'resource_manager' => 'Zend\Cache\Storage\Adapter\RedisResourceManager',
          'ttl' => 86400,
          'namespace' => 'users',
        ),
      ),
    ),
  ),
);

And it just call the serviceLocatior to fetch the RedisResourceManager.
Which could either be a custom factory to register the resources,
Or something built in that requires specific config keys to initialize potential resources.

array(
  'redis_resource_manager' => array(
    'resources' => array(
       'devredis' => array(
           'server' => 'devredis',
        ),
       'qaredis' => array(
           'server' => 'devredis',
           'database' => 1,
        ),
       'prodredis' => array(
           'server' => array(
                'host' => 'prodredis.prod',
                'port' => 9999,
            )
        )
    ),
  ),
);
@Ocramius Ocramius added the Cache label Apr 3, 2014
@marc-mabe
Copy link
Member

@icywolfy You are right, it's currently not possible to share such resources over different cache-storage instances without additional work on instantiating.

@Ocramius @weierophinney Thought's how to solve that. It's a very common question how to do that and it would be better if it's done by default using StorageCacheAbstractServiceFactory

@marc-mabe
Copy link
Member

@Ocramius @weierophinney ping

@Ocramius
Copy link
Member

@marc-mabe I don't have any clear overview on the topic right now: the entire *ResourceManager* logic is a bit obscure to me.

@Ocramius Ocramius added the bug label Aug 14, 2014
@marc-mabe
Copy link
Member

@Ocramius As the caching component is designed to have one cache instance per type of items this needs additional work on adapters working with connections for example. (You don't wont to create a new connection for each type of item to cache) - The *ResourceManager's should be used to share such resources between different cache instances. The issue here is that the *Resourcemanager's itself will be new instantiated by the service factory for each defined type.

@Ocramius
Copy link
Member

Yes, I understand the issue, and I agree that there should be only one ResourceManager per type, but I don't have the implementation details understanding to suggest how this should be solved.

@marc-mabe
Copy link
Member

@Ocramius can you ping the one how is good involved in service factory logic? I don't know who it is.

@Ocramius
Copy link
Member

That would still be me :-)

Marco Pivetta

http://twitter.com/Ocramius

http://ocramius.github.com/

On 14 August 2014 11:49, Marc Bennewitz notifications@github.com wrote:

@Ocramius https://github.com/Ocramius can you ping the one how is good
involved in service factory logic? I don't know who it is.


Reply to this email directly or view it on GitHub
#5787 (comment).

@GeeH
Copy link

GeeH commented Jun 27, 2016

This issue has been closed as part of the bug migration program as outlined here - http://framework.zend.com/blog/2016-04-11-issue-closures.html

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants