Laravel Cache Forever with * Possible * Expiry

时间:2014-07-13 13:46:48

标签: caching laravel laravel-4

我需要从外部API缓存返回的数据,听起来很简单但是......

我想用有效期缓存数据。我不希望缓存在该日期到期,我想尝试重新请求数据,如果成功,则覆盖旧数据。如果重新请求不成功,则应该保留旧数据。

基本上,我需要Cache::forever();一个有效期或一些自定义代码。

3 个答案:

答案 0 :(得分:3)

您可以轻松地将自己的方法添加为宏:

Cache::macro('untilUpdated', function ($key, $date, Closure $callback)
{
    if ( ! $date instanceof DateTime)
    {
        $date = Carbon::now()->addMinutes($date);
    }

    if (is_null($value = Cache::get($key)))
    {
        $data = $callback();

        Cache::forever($key, compact('date', 'data'));

        return $data;
    }

    if ($value['date'] >= $date && ($data = $callback()) !== false)
    {
        Cache::forever($key, compact('date', 'data'));

        return $data;
    }

    return $value['data'];
});

然后就像这样使用你的代码:

$value = Cache::untilUpdated('key', 10, function ()
{
    return API::call() ?: false;
});

答案 1 :(得分:2)

这是一个非常有用的模式,但不是许多高速缓存支持的模式,大多数将在到期日硬过期(删除)高速缓存条目。

实现起来非常简单,您需要做的就是在API响应对象中添加一个到期日期字段,填充它,用Cache::forever()存储响应。从缓存中检索响应时,请检查到期日期以及是否已通过,尝试加载和缓存新数据,或者回退以返回过时副本。

您可能希望在响应中添加另一个字段 - 您上次尝试刷新它的日期。然后,您可以使用它在新尝试新数据之间等待一段时间,如果API没有响应,这很方便。否则,在到期时间之后每次调用缓存数据都会导致浪费时间进行API调用。

您可以选择更复杂的模式,创建自己的新外观,包裹Laravel的Cache外观,并提供类似的方法。特别是,您可以编写自己的rememberForever方法实现,这样在每次调用缓存时,都会传递一个函数,如果响应丢失或过时,它将发出API请求。由于我不知道您的API查询是如何制作的,我无法为此提供示例,但无论如何第一个选项可能更容易!

答案 2 :(得分:1)

将您的下一个更新日期存储在任意位置,并使用一种简单的方法更新Cache::forever('your_key')的内容以检查新数据。

function checkForUpdates()
{
    $date = time();

    if (Cache::has('my_key'))
    {
        if ($date >= $date_from_db)
        {
            $data = $this->getUpdatedData();

            if ($data !== Cache::get('my_key'))
            {
                Cache::forever('my_key', $data)
            }
        }
    }
    else
    {
        Cache::forever('my_key', $this->getData());

        MyDateModel::insert(['next_update' => date('d-m-Y H:i:s', strtotime('+1 week'))]);
    }
}