概要
有効期限切れのキャッシュのレコードは自動的には削除されません。
取得時(getメソッド)に有効期限切れかチェックされ、有効期限が切れていれば削除されます。
https://stackoverflow.com/questions/38250191/when-does-laravel-clear-the-cache
背景
Laravelでデータベースキャッシュドライバを使用して、10s後に期限切れになるキャッシュを作成しました。
Cache::put('key', 'value', $seconds = 10);
cacheテーブルに以下のレコードが追加されました
key | value | expiration |
---|---|---|
key | s:5:"value"; | 1731198618 |
しかし、10s後になってもレコードは残っていてdocにもそのような記載が見当たらない為調査しました。
データベースキャッシュドライバは、期限切れのエントリを自動的に削除しない
こちらに記載されていました。
今回はLaravel 8.3を使っています。
最新だとこちらです
vendor/laravel/framework/src/Illuminate/Cache/DatabaseStore.php
/**
* Retrieve an item from the cache by key.
*
* @param string $key
* @return mixed
*/
public function get($key)
{
return $this->many([$key])[$key];
}
/**
* Retrieve multiple items from the cache by key.
*
* Items not found in the cache will have a null value.
*
* @return array
*/
public function many(array $keys)
{
if (count($keys) === 0) {
return [];
}
$results = array_fill_keys($keys, null);
// First we will retrieve all of the items from the cache using their keys and
// the prefix value. Then we will need to iterate through each of the items
// and convert them to an object when they are currently in array format.
$values = $this->table()
->whereIn('key', array_map(function ($key) {
return $this->prefix.$key;
}, $keys))
->get()
->map(function ($value) {
return is_array($value) ? (object) $value : $value;
});
$currentTime = $this->currentTime();
// If this cache expiration date is past the current time, we will remove this
// item from the cache. Then we will return a null value since the cache is
// expired. We will use "Carbon" to make this comparison with the column.
[$values, $expired] = $values->partition(function ($cache) use ($currentTime) {
return $cache->expiration > $currentTime;
});
if ($expired->isNotEmpty()) {
$this->forgetManyIfExpired($expired->pluck('key')->all(), prefixed: true);
}
return Arr::map($results, function ($value, $key) use ($values) {
if ($cache = $values->firstWhere('key', $this->prefix.$key)) {
return $this->unserialize($cache->value);
}
return $value;
});
}
期限切れのキャッシュは、取得時(getメソッド)にチェックされ、期限が切れていれば削除されます。
キャッシュのクリーンアップは、明示的にforgetやflushメソッドを呼び出す必要があります。
試しにgetで取得し、その後レコードがcacheテーブルから消えていることを確認します。
Cache::get('key');
確認した所レコードは確かに消えていました。
最後に
期限切れになったら消えると思っていたので勉強になりました。