Last active
June 23, 2025 16:08
-
-
Save garyblankenship/70cf6ac2763f4e1a181ea5b201547bef to your computer and use it in GitHub Desktop.
Laravel Cache::grace() return stale and dispatch revalidate #php
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Graceful cache retrieval and updating macro. | |
* | |
* First, tries to retrieve the cached value. If not found, uses a grace value. | |
* Schedules a background job for updating the cache if grace value is found. | |
* | |
* @param string $key The cache key to retrieve. | |
* @param int $ttl Time to live for the cache, in seconds. | |
* @param callable $callback Function to call for generating cache value. | |
* @return mixed The cached data or fresh data from the callback. | |
* | |
* Pseudocode: | |
* 1. Attempt to retrieve the value from the cache using the provided key. | |
* - If the value exists, return it. | |
* 2. If the value is not in the cache, attempt to retrieve the grace value. | |
* 3. If the grace value exists: | |
* - Schedule a background job to update the main cache value using the callback. | |
* - Return the grace value. | |
* 4. If the grace value does not exist: | |
* - Execute the callback to generate a new value. | |
* - Return the new value. | |
* | |
* Usage Example: | |
* Suppose you want to cache user data and refresh it every 10 minutes. You can use the 'grace' macro like this: | |
* | |
* $userData = Cache::grace('user_'. $userId, 600, function () use ($userId) { | |
* // Code to fetch user data from database or external service | |
* return User::find($userId); | |
* }); | |
* | |
* This will try to get 'user_$userId' from the cache. If it's not found, it will try to use the grace value. | |
* If neither is available, it will fetch the user data using the provided callback and cache it for future requests. | |
*/ | |
Cache::macro('grace', function ($key, $ttl, $callback) { | |
// Attempt to retrieve the cached value for the given key. | |
$value = Cache::get($key); | |
// If the cached value exists, return it immediately. | |
if ($value !== null) { | |
return $value; | |
} | |
// Retrieve a fallback value (grace value) from the cache. | |
$graceValue = Cache::get('grace.'.$key); | |
// If grace value exists, schedule a background job to refresh the cache. | |
if ($graceValue !== null) { | |
// The cache will be updated after the response is sent to the user. | |
// App::terminating(fn () => Cache::put($key, $callback(), $ttl)); | |
dispatch(function () use ($key, $ttl, $callback) { | |
Cache::put($key, $callback(), $ttl); | |
Cache::put('grace.'.$key, $callback(), $ttl * 2); | |
}); | |
} | |
// Return the grace value or, if not present, execute the callback for a fresh result. | |
return $graceValue ?? $callback(); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment