Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel occasionally failing to read cache

I am using laravel caching (the remember() method) on a website with a code like this:

$postedItems = Cache::remember('home_posted_items', $this->cacheTimes['postedItems'], function() {

    /* the stuff that prepares data */

    return ['items' => $items, 'firstItemNumber' => $firstItem];
});

The problem is that sometimes (every few days, I'd say) cached file seems to become corrupted and as a result I have downtime until the cache expires (unless I clear it manually).

Here is a part of the error stack that might be relevant:

[2017-02-04 22:01:34] production.ERROR: ErrorException: unserialize(): Error at offset 131059 of 131062 bytes in /home/path/to/app/vendor/laravel/framework/src/Illuminate/Cache/FileStore.php:78
Stack trace:
#0 [internal function]: Illuminate\Foundation\Bootstrap\HandleExceptions->handleError(8, 'unserialize(): ...', '/home/path/to/...', 78, Array)
#1 /home/path/to/app/vendor/laravel/framework/src/Illuminate/Cache/FileStore.php(78): unserialize('a:2:{s:7:"item...')
#2 /home/path/to/app/vendor/laravel/framework/src/Illuminate/Cache/FileStore.php(47): Illuminate\Cache\FileStore->getPayload('home_posted_ite...')
#3 /home/path/to/app/vendor/laravel/framework/src/Illuminate/Cache/Repository.php(98): Illuminate\Cache\FileStore->get('home_posted_ite...')
#4 /home/path/to/app/vendor/laravel/framework/src/Illuminate/Cache/Repository.php(202): Illuminate\Cache\Repository->get('home_posted_ite...')
#5 [internal function]: Illuminate\Cache\Repository->remember('home_posted_ite...', 1, Object(Closure))
#6 /home/path/to/app/vendor/laravel/framework/src/Illuminate/Cache/CacheManager.php(318): call_user_func_array(Array, Array)
#7 /home/path/to/app/bootstrap/cache/compiled.php(6089): Illuminate\Cache\CacheManager->__call('remember', Array)
#8 /home/path/to/app/app/Http/Controllers/HomeController.php(197): Illuminate\Support\Facades\Facade::__callStatic('remember', Array)

How to solve this problem?

From experience I know that clearing the cache solves the problem. So it seems that the issue is some corruption in files. I think if I could notice "the file is unreadable" and just clear the cache (Cache::forget(...)), it should solve the problem.

What would be the best way to notice such error? It seems that all the logic of retrieving the file is hidden inside the remember() method. Should I just unwrap it and use other methods, something like the following?

if (!($postedItems = @Cache::get('home_posted_items'))
{
    // prepare data

    $postedItems = ['items' => $items, 'firstItemNumber' => $firstItem];

    Cache::put('home_posted_items', $postedItems, $this->cacheTimes['postedItems']);
}
like image 658
Džuris Avatar asked Feb 04 '17 20:02

Džuris


1 Answers

IMHO could be a problem with file driver. I think that if you have a good web server able to handle concurrent requests the problem is that the file driver is not so able at handle concurrency.

And that is related to the fact that usually filesystems itself are not so good at handling different concurrent processes reading/writing to same file.

In the end I advise you to switch the driver to something more capable at handling concurrency, i.e Memcached or Redis, but also Database should be good enough.

You can find the same suggestion for session here, look at the second post, and I think that could be relevant for cache file driver too.

like image 101
dparoli Avatar answered Sep 30 '22 19:09

dparoli