我需要從外部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