flow-development-collection: neos/cache 5.3.25...5.3.26 Cannot add or modify cache entry because the affected keys are being modified by another process ("Flow_Session_Storage")

Description

Since neos/cache upgrade from 5.3.25 to 5.3.26 we (randomly?) got many of the following exception:

Neos\Cache\Exception: Cannot add or modify cache entry because the affected keys are being modified by another process ("Flow_Session_Storage") (1594725688)

#0 Packages/Libraries/neos/cache/Classes/Frontend/VariableFrontend.php(68): Neos\Cache\Backend\RedisBackend->set('...', '...', Array, 0)
#1 Data/Temporary/Production/Cache/Code/Flow_Object_Classes/Neos_Flow_Session_Session.php(479): Neos\Cache\Frontend\VariableFrontend->set('...', Array, Array, 0)
#2 Data/Temporary/Production/Cache/Code/Flow_Object_Classes/Neos_Flow_Session_Session.php(751): Neos\Flow\Session\Session_Original->putData('Neos_Flow_Secur...', Array)
#3 Data/Temporary/Production/Cache/Code/Flow_Object_Classes/Neos_Flow_Session_Session.php(689): Neos\Flow\Session\Session_Original->storeAuthenticatedAccountsInfo(Array)
#4 Packages/Framework/Neos.Flow/Classes/ObjectManagement/ObjectManager.php(561): Neos\Flow\Session\Session_Original->shutdownObject()
#5 Packages/Framework/Neos.Flow/Classes/ObjectManagement/ObjectManager.php(464): Neos\Flow\ObjectManagement\ObjectManager->callShutdownMethods(Object(SplObjectStorage))
#6 Data/Temporary/Production/Cache/Code/Flow_Object_Classes/Neos_Flow_Security_Context.php(219): Neos\Flow\ObjectManagement\ObjectManager->Neos\Flow\ObjectManagement\{closure}()
#7 Data/Temporary/Production/Cache/Code/Flow_Object_Classes/Neos_Flow_Security_Context.php(219): Closure->__invoke()
#8 Packages/Framework/Neos.Flow/Classes/ObjectManagement/ObjectManager.php(465): Neos\Flow\Security\Context_Original->withoutAuthorizationChecks(Object(Closure))
#9 [internal function]: Neos\Flow\ObjectManagement\ObjectManager->shutdown('Runtime', 'Neos\\Flow\\Core\\...')
#10 Packages/Framework/Neos.Flow/Classes/SignalSlot/Dispatcher.php(140): call_user_func_array(Array, Array)
#11 Packages/Framework/Neos.Flow/Classes/Core/Bootstrap.php(467): Neos\Flow\SignalSlot\Dispatcher->dispatch('Neos\\Flow\\Core\\...', 'bootstrapShutti...', Array)
#12 Packages/Framework/Neos.Flow/Classes/Core/Bootstrap.php(137): Neos\Flow\Core\Bootstrap->emitBootstrapShuttingDown('Runtime')
#13 Packages/Framework/Neos.Flow/Classes/Http/RequestHandler.php(114): Neos\Flow\Core\Bootstrap->shutdown('Runtime')
#14 Packages/Framework/Neos.Flow/Classes/Core/Bootstrap.php(112): Neos\Flow\Http\RequestHandler->handleRequest()
#15 Web/index.php(27): Neos\Flow\Core\Bootstrap->run()
#16 {main}

We can’t relate the exception with a specific action, it seems to happen across multiple different controllers. Our Caches.yaml sets the flow session caches to redis as follows:

Flow_Session_MetaData:
  persistent: true
  backend: 'Neos\Cache\Backend\RedisBackend'
  backendOptions:
    defaultLifetime: 0
    hostname: '%env:REDIS_HOST%'
    password: '%env:REDIS_PASSWORD%'
    port: '%env:REDIS_PORT%'
    database: 0

Flow_Session_Storage:
  persistent: true
  backend: 'Neos\Cache\Backend\RedisBackend'
  backendOptions:
    defaultLifetime: 0
    hostname: '%env:REDIS_HOST%'
    password: '%env:REDIS_PASSWORD%'
    port: '%env:REDIS_PORT%'
    database: 0 

The upgrade from neos/cache 5.3.25 to 5.3.26 also seems to increase the number of requests to redis. I’ve attached a list of commands that redis sees on a single web request (opening the home page in our case) for the two versions:

5.3.25.txt 5.3.26.txt

5.3.25 causes 32 redis commands, with 5.3.26 it’s 56 (+3 WATCH, +10 TTL, +10 PERSIST). The number also seemed pretty high before, is this to be expected or are we doing something wrong?

Steps to Reproduce

We are not able to consistently reproduce the issue. What we can say is that we run multiple instances of the app using the same Redis backend. We’ve also seen the exception mostly on production systems with higher user traffic. Since we’ve downgraded neos/cache back to 5.3.25 we didn’t see the exception anymore.

Expected behavior

No exceptions

Actual behavior

Random exceptions

Affected Versions

neos/cache 5.3.26 (did not happen with 5.3.25) neos/flow 5.3.26

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 21 (17 by maintainers)

Most upvoted comments

So we discussed this today in our @neos/unicorn weekly and finally concluded we will have to revert #2052 unfortunately. The first idea was to just remove the exception, since if the setting of the cache fails, that should not be too problematic, but we do have persistent caches and places where a failing set operation is something the caller should know. We also can not simply strip away tags from this backend as there are too many things depending on the tags in the one or the other way.

Given the initial issue was that tags are not evicted and pile up, setting a TTL on the tags would still be useful. But watching them for changes to make the update atomic is apparently an issue in our usage of caches and tags. Maybe it’s okay to have inconsistent tag entries and we need to deal with them. Also, we’d like to investigate how symfony redis cache adapter behaves and if it works well maybe support an adapter to symfony caches. @kitsunet want’s to take a look

@albe @kitsunet if you need any help with this or want insights on our issues then feel free to contact me. I am happy to help.

Release has been tagged, so this issue should be resolved. Still if someone is up to create an issue/PR to add TTL that is highly appreciated. Will close this issue for now though. Thanks everyone for their input and patience!

We are currently in discussion with redis experts, hope to provide some more input soon

We encountered this issue on the sessions too, we managed to patch it by overriding the redis backend to exclude the ‘Flow_Session_MetaData:tag:session’ tag from the watch. I suspect allowing a definition of safe and unsafe to watch tags may be the best solution.

I couldn’t find a usage of RouterCachingService::flushCachesForUriPath($uriPath) at least in Flow core so maybe that is actually unused? @bwaidelich do you know anything more about that?).

I don’t… I think this (IMO rather quirky) caching part was added for the RedirectHandler package.