Redis Cache By Xon

Redis Cache By Xon 2.18.7

No permission to download
I think this would be on XF to redesign the way they do caching, not this add-on.

if it can't pull from the cache after a retry, it should compute/pull direct and send an alert of some sort "Hey admin, cache hit failed at X time".

Yes, I agree. I just wanted to reconfirm with @Xon that my expectations that XenForo should fallback gracefully if Redis (or any caching instance) wasn't out of line before moving on to report this "bug" with caching.

Edit: From what I can tell the fatal CredisException is thrown directly from Credis_Client->connect() inside the add-on’s code (Client.php line ~607).The add-on is the one deciding how to handle (or not handle) connection failures. SV\RedisCache\SymfonyCache\Redis.php is already intercepting calls (e.g., getItems, mGet) and timing them. It would be straightforward for the add-on to wrap the initial connect() call in a try/catch block and, on failure, return a fallback cache provider (e.g., a NullCache, ArrayCache, or XenForo’s default FileCache).

XenForo expects the cache object (from config['cache']['provider']) to behave like PSR-16 SimpleCache — i.e., it should never throw exceptions on get/set/delete when the backend is unavailable; it should return null/false or a default value gracefully.Most production Redis cache libraries (e.g., Symfony’s RedisAdapter, Laravel’s Redis store) do exactly that: they catch connection errors and degrade silently or fall back. Credis itself is quite low-level and throws aggressively — that would make this add-on responsible for adding that resilience layer.

Something like...
PHP:
public function getItems(array $keys)
{
    try {
        if (!$this->redis->isConnected()) {
            $this->redis->connect(...);  // or reconnect logic
        }
        return $this->redis->mGet($keys);
    } catch (CredisException $e) {
        // Log once: "Redis unavailable, falling back to file cache"
        $this->fallbackCache = $this->createFallbackCache(); // e.g. FileCache or NullCache
        return $this->fallbackCache->getItems($keys);
    }
}
// Similar try/catch around set, delete, clear, has, etc.

This could be done on first failure, then to fallback and stay there until Redis is detected alive again (periodic health check). This would prevent the site-wide fatals like I experienced during Redis restarts/outages.
 
Last edited:
Blindly using a failback caching adaptor is an incredible bad idea. And it is not a feature I will add or expect XF to add.

XenForo expects the cache object (from config['cache']['provider']) to behave like PSR-16 SimpleCache — i.e., it should never throw exceptions on get/set/delete when the backend is unavailable;
That is incorrect. Nothing in the PSR-16 spec says that, at all

Most production Redis cache libraries (e.g., Symfony’s RedisAdapter, Laravel’s Redis store) do exactly that: they catch connection errors and degrade silently or fall back.
The add-on has a basic form of retry on a new connection failed logic, it just isn't very useful as it doesn't stall for the better part of a second to wait for redis to come back.

While Symfony’s RedisAdapter/Laravel’s Redis use PhpRedis or predis, and Laravel uses PhpRedis's retry new connection logic they absolutely don't silently degrade or return failure if the connection to the caching backend stops working.

Both PhpRedis and predis will aggressively throw exception, and neither Symfony's or Laravel's wrapper layers will catch most exceptions. There are some edge cases where Laravel will swallow exceptions when using the pipelining feature but depending on the exception this will leave the connection between php and redis in a broken state, so lol.
 
Last edited:
Back
Top Bottom