Connor Peet
Connor Peet

Reputation: 6265

Laravel Selective Caching

I'm developing one of my first applications with the Laravel 4 framework (which, by the way, is a joy to design with). For one component, there is an AJAX request to query an external server. The issue is, I want to cache these responses for a certain period of time only if they are successful.

Laravel has the Cache::remember() function, but the issue is there seems to be no "failed" mode (at least, none described in their documentation) where a cache would not be stored.

For example, take this simplified function:

try {
    $server->query();
} catch (Exception $e) {
    return Response::json('error', 400);
}

I would like to use Cache::remember on the output of this, but only if no Exception was thrown. I can think of some less-than-elegant ways to do this, but I would think that Laravel, being such an... eloquent... framework, would have a better way. Any help? Thanks!

Upvotes: 4

Views: 3212

Answers (3)

dwenaus
dwenaus

Reputation: 3326

This is what worked for me:

if (Cache::has($key)) {
    $data = Cache::get($key);
} else {
    try {
        $data = longQueryOrProcess($key);
        Cache::forever($key, $data); // only stored when no error
    } catch (Exception $e) {
        // deal with error, nothing cached
    }
}

And of course you could use Cache::put($key, $data, $minutes); instead of forever

Upvotes: 4

Thom
Thom

Reputation: 2493

We're working around this by storing the last good value in Cache::forever(). If there's an error in the cache update callback, we just pull the last value out of the forever key. If it's successful, we update the forever key.

Upvotes: 1

Markus Hofmann
Markus Hofmann

Reputation: 3447

I found this question, because I was looking for an answer about this topic.

In the meanwhile I found a solution and like to share it here:
(also check out example 2 further on in the code)

<?php
/**
 * Caching the query - Example 1
 */

function cacheQuery_v1($server)
{
    // Set the time in minutes for the cache
    $minutes = 10;

    // Check if the query is cached
    if (Cache::has('db_query'))
    {
        return Cache::get('db_query');
    }

    // Else run the query and cache the data or return the 
    // error response if an exception was catched
    try
    {
        $query = $server->query(...);
    }
    catch (Exception $e)
    {
        return Response::json('error', 400);
    }

    // Cache the query output
    Cache::put('db_query', $query, $minutes);

    return $query;
}


/**
 * Caching the query - Example 2
 */

function cacheQuery_v2($server)
{
    // Set the time in minutes for the cache
    $minutes = 10;

    // Try to get the cached data. Else run the query and cache the output.
    $query = Cache::remember('db_query', $minutes, function() use ($server) {
        return $server->query(...);
    });

    // Check if the $query is NULL or returned output
    if (empty($query))
    {
        return Response::json('error', 400);
    }

    return $query;
}

I recommend you to use Laravel's Eloquent ORM and/or the Query Builder to operate with the Database.

Happy coding!

Upvotes: 1

Related Questions