我需要从外部API缓存返回的数据,听起来简单,但...Laravel缓存永远与*可能*到期
我想和到期日来缓存数据。我不希望缓存在该日期过期,我想尝试重新请求数据,如果成功,请覆盖旧数据。如果重新请求不成功,它应该只保留旧数据。
基本上,我需要Cache::forever();
带有失效日期或一些自定义代码。
我需要从外部API缓存返回的数据,听起来简单,但...Laravel缓存永远与*可能*到期
我想和到期日来缓存数据。我不希望缓存在该日期过期,我想尝试重新请求数据,如果成功,请覆盖旧数据。如果重新请求不成功,它应该只保留旧数据。
基本上,我需要Cache::forever();
带有失效日期或一些自定义代码。
您可以轻松地添加自己的方法作为宏:
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;
});
这是一个非常有用的模式,但并不是许多缓存支持的模式,大多数缓存将在到期日期后过期(删除)高速缓存条目。
实现你自己很简单,你需要做的就是添加一个到期日期字段到你的API响应对象中,填充它,存储响应Cache::forever()
。当您从缓存中检索响应时,请检查到期日期以及是否通过,尝试加载并缓存新数据,或者后退以返回陈旧副本。
您可能需要在响应中添加另一个字段 - 上次尝试刷新它的日期。然后,您可以使用它在新尝试新数据之间等待一段时间,如果API没有响应,这很方便。否则,在到期之后每次调用缓存数据都会浪费时间进行API调用。
您可以选择更复杂的图案,创建自己的新外观,该外观包装Laravel的Cache
外观,并提供类似的方法。特别是,您可以编写自己的rememberForever
方法的实现,以便在每次调用缓存时,都会传递一个函数,以便在响应丢失或失效时发出API请求。由于我不知道你的API查询是如何产生的,所以我无法提供这样的示例,但无论如何,第一种选择可能更简单!
将您的下一个更新日期存储在任何你喜欢的地方,只需使用简单的方法更新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'))]);
}
}
这看起来相当真棒。我在哪里粘贴这个代码(宏本身)? – atwright147
@ atwright147 - 任何你想要的。在你的'start/global.php','routes.php'中,或者在你的路径文件旁边创建一个'macros.php'文件,并将其包含在过滤器文件后面的'start/global.php'末尾。 –
这太棒了!我已更正原始帖子中的一个小回复错误。另外,我一直在调用我的'untilUpdated()' – atwright147