XF 2.3 When using cache, does the cache item need to be explicitly saved in the 'get' callback?

Kevin

Well-known member
Using the example from @Jeremy P in this post about using the Symfony cache with XF 2.3, if we are using a callback to get the results if the cache key is not present or expired, do we need to explicitly save the item to cache in the callback function? Or do we need to do a 'getIem' & 'isHit' in combination with the callback? 🤔

In the quick test below, I'm always hitting the callback and am never hitting the cached copy.

Code:
$cacheKey = 'cinvin.testwidget';
$cache = \XF::app()->cache('', true, false);

if ($cache)
{
    $widgetRendered = $cache->get(
        $cacheKey,
        function (\Symfony\Contracts\Cache\ItemInterface $item): string
        {
            $item->expiresAfter(3600); // TTL
            $widgetRendered = $this->getWidgetRendered();
            return $widgetRendered;
        }
    );
}
else
{
    return $this->getWidgetRendered();
}
 
I can't reproduce this, do you have a cache configured? The callback is executed and saved in the cache if it does not exist (or is expired), and pulled from the cache otherwise. Manually fetching the items or checking if it's a hit are for the PSR-6 interface, but I'd really recommend sticking with the cache contract approach instead. The only reason we still use PSR-6 in the core is to preserve backwards compatibility.

For example, this code dumps the same output every time since the random value is cached:

PHP:
$callback = fn(): int => random_int(0, 10);

$cache = \XF::app()->cache('', true, false);
if ($cache)
{
    $output = $cache->get(
        'cinvin.testwidget',
        function (ItemInterface $item) use ($callback): int
        {
            $item->expiresAfter(3600);

            return $callback();
        }
    );
}
else
{
    $output = $callback();
}

dump($output);
 
I can't reproduce this, do you have a cache configured? The callback is executed and saved in the cache if it does not exist (or is expired), and pulled from the cache otherwise. Manually fetching the items or checking if it's a hit are for the PSR-6 interface, but I'd really recommend sticking with the cache contract approach instead. The only reason we still use PSR-6 in the core is to preserve backwards compatibility.
Thank you for taking the time for the try to duplicate the issue, your test & first question about the cache got me on the right path.

In my sandbox environment I must've FUBAR'ed the config settings enough times that I broke something because even though I had the cache enabled (and with if ($cache) returning true) I couldn't get your example code responding right either. So I took the approach of cleaning out the sandbox a bit, made sure the cache settings matched a production site that I knew was good, and success!

I updated my add-on & accompanying widget, tested the heck out of it in the sandbox, and it's now totally working perfectly with the cache addition.

The end result is a faster loading page and a better understanding of implementing cache so, seriously, thank you.
 
Back
Top Bottom