md-systems/redis

Document how use redis for cache_container

Berdir opened this issue · 4 comments

That bin is special because it's used before the actual container is used, as it contains the actual container.

To use it, there are two requirements.

  1. redis must be in the hardcoded composer autoload namespaces or it won't find the classes. For that to work, the top-level composer.json must contain redis as a module. and composer dump-autoloader needs to be called (or anything that calls it). This needs to be better documented, maybe an alternative would be to manually load the required fields through settings.php. clarify and properly document this.
  2. You need to put this into your settings.php:
  // Use redis for container cache.
  $settings['bootstrap_container_definition'] = [
    'parameters' => [],
    'services' => [
      'redis.factory' => [
        'class' => 'Drupal\redis\ClientFactory',
      ],
      'cache.backend.redis' => [
        'class' => 'Drupal\redis\Cache\CacheBackendFactory',
        'arguments' => ['@redis.factory', '@cache_tags_provider.container'],
      ],
      'cache.container' => [
        'class' => '\Drupal\redis\Cache\PhpRedis',
        'factory' => ['@cache.backend.redis', 'get'],
        'arguments' => ['container'],
      ],
      'cache_tags_provider.container' => [
        'class' => 'Drupal\redis\Cache\RedisCacheTagsChecksum',
        'arguments' => ['@redis.factory'],
      ],
    ],
  ];

@Berdir Yes, that is correct. The easiest way is to just register the PSR-4 namespace via the given loader:

$class_loader->addPsr4('Drupal\\redis\\', 'modules/redis/src');

As the class loader is available in settings.php.

Thanks for the feedback. Indeed, that makes sense, I'll add that to the documentation.

If anyone was trying to get this working, add this to your settings.php.

<?php

if (class_exists(\Composer\Autoload\ClassLoader::class)) {
  $loader = new \Composer\Autoload\ClassLoader();
  $loader->addPsr4('Drupal\\redis\\', 'modules/redis/src');
  $loader->register();
  $settings['bootstrap_container_definition'] = [
    'parameters' => [],
    'services' => [
      'cache.container' => [
        'class' => 'Drupal\redis\Cache\PhpRedis',
        'factory' => ['@cache.backend.redis', 'get'],
        'arguments' => ['container', '@redis', '@cache_tags_provider.container', '@serialization.phpserialize'],
      ],
      'cache_tags_provider.container' => [
        'class' => 'Drupal\redis\Cache\RedisCacheTagsChecksum',
        'arguments' => ['@redis.factory'],
      ],
      'redis' => [
        'class' => 'Redis',
      ],
      'cache.backend.redis' => [
        'class' => 'Drupal\redis\Cache\CacheBackendFactory',
        'arguments' => ['@redis.factory', '@cache_tags_provider.container', '@serialization.phpserialize'],
      ],
      'redis.factory' => [
        'class' => 'Drupal\redis\ClientFactory',
      ],
      'serialization.phpserialize' => [
        'class' => 'Drupal\Component\Serialization\PhpSerialize',
      ],
    ],
  ];
}

?>

Hi guys,
I just try this definition with result:

Error: Class 'Redis' not found in Drupal\Component\DependencyInjection\PhpArrayContainer->createService() (line 89 of /Users/michal.landsman/localhost/marianne-thunder/docroot/core/lib/Drupal/Component/DependencyInjection/PhpArrayContainer.php).

Without $settings['bootstrap_container_definition'] it works.
Why you write this definition here?