Skip to content

Redis Cache Setup in Framework Module #58108

@reashetyrr

Description

@reashetyrr

Symfony version(s) affected

7.x

Description

While setting up a Redis cache for the cache.app within the Framework module, I encountered an issue where executing migration commands resulted in an error. The error occurred because PHP attempted to connect to tcp://127.0.0.1:6379.

After performing some debugging, I identified that the issue originates from the generated file getRedisSessionHandlerService.php. Specifically, the problem lies in lines 26-28, where the following code is present:

$a = new \Predis\Client();
$a->connect($container->getEnv('REDIS_URL'));
$a->auth($container->getEnv('REDIS_PASSWORD'));

The issue arises from the usage of the connect method in the Predis\Client class. According to the Predis documentation, the connection configuration should be passed during the instantiation of the Predis\Client rather than through the connect method, as this method does not accept any arguments.

How to reproduce

  1. setup an env with REDIS_URL which is a proper dsn to a redis server
  2. have an optional REDIS_PASSWORD or set the password in the redis_url dsn like: {tcp|redis}://{password}@{host}:{port}/{db}
  3. update framework.yaml to set the app parameter under the framework.cache key to be: cache.adapter.redis like:
    cache:
        app: cache.adapter.redis
        default_redis_provider: '%env(REDIS_URL)%'
  1. in service.yaml add a service like: Redis
    Redis:
        class: \Predis\Client
        calls:
            - [connect, ['%env(REDIS_URL)%']]
            - auth: ['%env(REDIS_PASSWORD)%']
  1. in service.yaml add a service for redissessionhandler:
Symfony\Component\HttpFoundation\Session\Storage\Handler\RedisSessionHandler:
        arguments:
            - '@Redis'
  1. try to run a command such as: symfony console make:migration

Possible Solution

$redisUrl = $container->getEnv('REDIS_URL');
$redisPassword = $container->getEnv('REDIS_PASSWORD') ?? null;

$parsedUrl = parse_url($redisUrl);
if (false === $parsedUrl) {
    throw new \InvalidArgumentException('Invalid REDIS_URL provided.');
}

$scheme = $parsedUrl['scheme'] ?? 'tcp';
$host = $parsedUrl['host'] ?? '127.0.0.1';
$port = $parsedUrl['port'] ?? 6379;

if (isset($parsedUrl['user'])) {
    $redisPassword = $parsedUrl['user'];
}

$database = 0;

if (isset($parsedUrl['path'])) {
    $foundPath = ltrim($parsedUrl['path'], '/');
    if (is_numeric($foundPath)) {
        $database = (int) $foundPath;
    }
}

if (isset($parsedUrl['query'])) {
    parse_str($parsedUrl['query'], $queryParams);

    if (isset($queryParams['dbindex'])) {
        $database = (int) $queryParams['dbindex'];
    }
}

$predisOptions = [
    'scheme' => $scheme,
    'host' => $host,
    'port' => $port,
    'database' => $database,
    'password' => $redisPassword,
];

$a = new \Predis\Client($predisOptions);
$a->connect($container->getEnv('REDIS_URL'));

Additional Context

Current running environment

  • PHP version:
PHP 8.3.10 (cli) (built: Jul 30 2024 15:15:32) (NTS Visual C++ 2019 x64)
Copyright (c) The PHP Group
Zend Engine v4.3.10, Copyright (c) Zend Technologies
    with Xdebug v3.3.2, Copyright (c) 2002-2024, by Derick Rethans
  • OS: Windows 10
  • Symfony cli version:
Symfony CLI version 5.10.2 (c) 2021-2024 Fabien Potencier (2024-07-19T11:09:07Z - stable)
Symfony CLI helps developers manage projects, from local code to remote infrastructure
  • Symfony version: 7.1.3
  • Redis client: Predis

Without the proposed fix:

In AbstractConnection.php line 144:
                                                                                                     
  No connection could be made because the target machine actively refused it [tcp://127.0.0.1:6379]  
                                                                                                     

make:migration [--formatted] [--configuration [CONFIGURATION]]


Process finished with exit code 255

With the proposed fix fix

created: file://C:\Users\{user}\PhpstormProjects\smoelenboek/migrations/Version20240827190258.php#L1migrations/Version20240827190258.php

           
Success! 


Review the new migration then run it with php bin/console doctrine:migrations:migrate
See https://symfony.com/doc/current/bundles/DoctrineMigrationsBundle/index.html

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions