Skip to content

[Cache] cache:pool:clear fails if Redis uses prefix #41012

@gboubel

Description

@gboubel

Symfony version(s) affected: 4.4.21

Description
The cache:pool:clear command does not delete any keys when using a Redis connection with prefix set.

How to reproduce

I'm using the Redis extension as the cache.adapter.redis adapter's connection and setting a prefix on the Redis class with the following services.yaml lines:

    #REDIS
    Redis:
        class: Redis
        lazy: true
        calls:
            -   method: connect
                arguments:
                    - '%redis_host%'      # host: string. can be a host, or the path to a unix domain socket.
                    - '%redis_port%'      # port:  int, optional
                    - 0                   # float, value in seconds (optional, default is 0 meaning unlimited)
                    - null                # reserved: should be NULL if retry_interval is specified
                    - 200                 # retry_interval: int, value in milliseconds (optional)
                    - 0                   # read_timeout: float, value in seconds (optional, default is 0 meaning unlimited)
            -   method: setOption
                arguments:
                    - !php/const Redis::OPT_PREFIX
                    - '%env(APP_ENV)%_store:'

This makes the Redis prefixed in production like 'prod_store'. The cache is created and writes just fine in that namespace, but when trying to clear a specific cache using cache:pool:clear command or all of them with cache:pool:clear cache.global_clearer , the cache remains intact without changes.

Possible Solution
I believe the issue is that here in the RedisTrait the line that scans for cache keys to delete:

$host->scan($cursor, $namespace.'*', 1000)

This generates the following redis command:

"SCAN" "0" "COUNT" "1000" "MATCH" "tdYoyvcfPq:*"

which doesn't honor the prefix so it finds no matches. It would have to be something like

$host->scan($cursor, $host->_prefix($namespace.'*'), 1000)

which would create

"SCAN" "0" "COUNT" "1000" "MATCH" "prod_store:tdYoyvcfPq:*"

Additional context

Ultimately this is because the Redis class is a little strange in how it handles prefixes. It automatically adds them for set and deleting functions, but not on scans. There is actually a mention of this in a phpredis/phpredis issue.

Then again maybe I missed a symfony config value somewhere that I'm supposed to set 😏

If this is a legit bug, I'd be happy to take a crack and submit a pull request fix.

Metadata

Metadata

Assignees

No one assigned

    Labels

    CacheHelp wantedIssues and PRs which are looking for volunteers to complete them.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions