Steve Childs
Steve Childs

Reputation: 1872

Symfony2 - How to set Doctrine APC cache prefix with multiple apps

Update: See bottom of post ( this was orginially posted when we were using SF 2.3, we're now on 2.7.0 )

We've got multiple Symfony apps running on our server, but we appear to be getting cache pollution across the sites due to all the doctrine ORM cache entries being prefixed with 'sf2'.

From spending the last 30 mins googing around, there doesn't appear to be an easy solution.

The first ones suggested using the ProjectConfiguration.class.php - but that appears to be a Symfony 1 thing.

The next possible solution was to use the ApcUniversalClassLoader class (as per this question on SO: Multiple Symfony2 Sites using APC Cache).

The problem is that our setup uses composer to autoload, so we can't simply use the code as per that example.

The class caching side of APC is fine, you can set the key in the front controller, but it doesn't set the key for the doctrine cache.

Has anyone got any thoughts please as currently we're having to disable APC for doctrine on all but the first app.

Frontcontroller:

<?php

use Symfony\Component\ClassLoader\ApcClassLoader;
use Symfony\Component\HttpFoundation\Request;

require_once __DIR__.'/../app/bootstrap.php.cache';

// Use APC for autoloading to improve performance.
// Change 'sf2' to a unique prefix in order to prevent cache key    conflicts
// with other applications also using APC.
$loader = new ApcClassLoader('app_1', $loader);
$loader->register(true);

require_once __DIR__.'/../app/AppKernel.php';

$kernel = new AppKernel('prod', false);
$kernel->loadClassCache();

// wrap the default AppKernel with the AppCache one
require_once __DIR__.'/../app/AppCache.php';
$kernel = new AppCache($kernel);

Request::enableHttpMethodParameterOverride();
$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);

-- Clarify -- Just to clarify, the code above refers the APC cache for the classes, this works as above and is fine. what we can't seem to change is the default namespaces for the doctrine ORM APC entries, these seem to be fixed and thus clash with each running instance.

-- Update --

After trying Zerrvox's suggestion of setting the namespace, it didn't seem to work, the main caches are still using the default namespaces. It wouldn't be so bad if they were randomly generated when the cache was cleared, but the default namespaces are the same on both my vagrant box and the live box and the caches were generated on the separate boxes, so its obviously not random.

These methods in the appProdProjectContainer class in the cache still refer to the default namespaces.

protected function getDoctrineCache_Providers_Doctrine_Orm_DefaultMetadataCacheService()
{
....        
$instance->setNamespace('sf2orm_default_9e755ef08ba52b507455ecd06d0a648985c9593b15aca1522b4725acaaf77ce6');
        return $instance;
}

// Same for...

protected function getDoctrineCache_Providers_Doctrine_Orm_DefaultQueryCacheService   

protected function getDoctrineCache_Providers_Doctrine_Orm_DefaultResultCacheService

Upvotes: 4

Views: 3175

Answers (2)

Artur R.
Artur R.

Reputation: 247

It works in my case (Symfony 2.8 - 3.4):

doctrine_cache:
    providers:
        my_redis:
            type: redis
            namespace: "%prefix%"
            aliases:
              - redis_cache

Where "namespace" is prefix for given app setted up in parameters.yml

Upvotes: 1

Zerrvox
Zerrvox

Reputation: 81

You don't specify if you are talking about doctrine ORM cache or annotation cache using Doctrine Annotations.

Anyway you can create your own APC cache service which can be used for both by defining a service in Symfony like this (yml)

   app.doctrine.apc_cache:
       class: Doctrine\Common\Cache\ApcCache
       calls:
           - [setNamespace, ["app_namespace"]]

-- Update --

Did you specify the defined service as metadata cache for doctrine. See the configuration reference for the Doctrine bundle configuration http://symfony.com/doc/current/reference/configuration/doctrine.html#caching-drivers

   doctrine:
       orm:
           metadata_cache_driver:
               type: service
               id: app.doctrine.apc_cache

Upvotes: 3

Related Questions