Skip to content

PsrCachedReader::fetchFromCache might return null instead of array under high request rate #457

@dshatovskiy

Description

@dshatovskiy

Hi everyone.

We are fandom and very rare error
request.CRITICAL: Uncaught PHP Exception TypeError: "Doctrine\Common\Annotations\PsrCachedReader::fetchFromCache(): Return value must be of type array, bool returned" at ...

This usually happens on applications with the high request rate and some of such caches are empty.
The working scenario - new code release which requires to flush caches in order to new changes took in place.
When we debug the problem - it is appeared, when some of the requests hit that method and retrieve CacheItem, it has isHit property "true" but value "null".
Obviously, we made sure nothing overrides this cache items with null values.
Therefore we made conclusion this is "race condition" problem

We tried different approaches as a hotfix:

  1. Allowing null values in this method doesn't work for us because it triggers error in some other vendor code
  2. Using CacheInterface::get instead of CacheItemPoolInterface makes hit rate better but not ideal and still got small % of errors during load testing
  3. The only working variant we had giving us 100% rate looks quite strange but anyway
        $cacheKey = rawurlencode($cacheKey);

        $item = $this->cache->getItem($cacheKey);
        $raceConditionHit = $item->isHit() && !\is_array($item->get());

        if (($this->debug && ! $this->refresh($cacheKey, $class)) || ! $item->isHit() || $raceConditionHit) {
            if ($raceConditionHit) {
                usleep(100);
            }
            $this->cache->save($item->set($this->delegate->{$method}($reflector)));
        }

        return $item->get();

We understand that problem is quite unique and the package is not actively maintained, but since this class is final, it is hard to override this code and it would be great to have working solution in one of the next releases.

Thank you

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions