skip to Main Content

My symfony application has multiple instances that are running in seperate docker containers.

And I have configured my app.cache to use redis:

framework:
    cache:
        app: cache.adapter.redis

I have the same prefix_seed:

framework:
    cache:
        prefix_seed: 'dev'

As a result I’m getting in redis something like this:

1605259288.470950 [0 172.18.0.28:55044] "MGET" "HnMEIyUlZ+:workers.restart_requested_timestamp"
1605259288.471680 [0 172.18.0.28:55044] "SET" "HnMEIyUlZ+:workers.restart_requested_timestamp" "d:1605259288.471522;"
1605259314.483389 [0 172.18.0.29:42884] "MGET" "8TMgMtnOAG:workers.restart_requested_timestamp"

As you can see from the above 2 different instances are trying to fetch value from redis by the same key workers.restart_requested_timestamp but the prefix is different even with the same prefix_seed.

In this example I’m using messenger component, and I want to stop workers running everywhere by stop-workers command (through the shared redis). But generally speaking this is related to cache configuration.

How to overcome this and tell both applications to use same pool? What is the configuration for this?

2

Answers


  1. Chosen as BEST ANSWER

    Finally, I found the solution. There's an option to create your own cache pool with mapped adapter to it. The main trick here is to pass the tag with namespace to your adapter (name is also should be cache.pool):

    framework:
        cache:
            pools:
                cache.redis_shared_pool:
                    adapter: app.cache_shared_redis_adapter
    
    services:
        app.cache_shared_redis_adapter:
            parent: 'cache.adapter.redis'
            tags:
                - { name: 'cache.pool', namespace: 'shared' }
    

    That's it! All your keys in redis will be prefixed with shared:. Now you should pass your @cache.redis_shared_pool to any service you want.

    And as for the messenger component, we should override the services (but I'm not sure this is the best way):

    console.command.messenger_stop_workers:
        class: SymfonyComponentMessengerCommandStopWorkersCommand
        arguments:
           $restartSignalCachePool: "@cache.redis_shared_pool"
    
    messenger.listener.stop_worker_on_restart_signal_listener:
        class: SymfonyComponentMessengerEventListenerStopWorkerOnRestartSignalListener
        arguments:
           $cachePool: "@cache.redis_shared_pool"
    

  2. In the symfony framework bundle’s configuration definition you could find:

        private function addCacheSection(ArrayNodeDefinition $rootNode)
        {
            $rootNode
                ->children()
                    ->arrayNode('cache')
                        ->info('Cache configuration')
                        ->addDefaultsIfNotSet()
                        ->fixXmlConfig('pool')
                        ->children()
                            ->scalarNode('prefix_seed')
                                ->info('Used to namespace cache keys when using several apps with the same shared backend')
                                ->example('my-application-name')
                            ->end()
                            ...
    

    prefix_seed is exactly what you are looking for.
    Check the documentation here: https://symfony.com/doc/current/reference/configuration/framework.html#prefix-seed

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search