[11.x] Add `remaining` method to get the expiration timestamp of a cache key
Synopsis
I'm running a large(ish) query and caching the data for a set period of time, and wanting to display to the user how long is remaining until the data is refreshed in the cache. To test this, I manually modified the FileStore and DatabaseStore classes within my project's vendor/ directory to add a method that will return the expiry time as a human readable string (or optionally the UNIX timestamp).
This is only a draft PR because protocols such as Memcached do not provide an efficient API to retrieve the expiry time of a cached item, unless you store the expiry time alongside the actual data being cached, but that would likely be a breaking change within the Laravel codebase if this was to happen. I have also not provided methods for other stores such as RedisStore or DynamoDbStore etc. as I was quickly testing solutions before drafting this PR.
I am open to seeing suggestions as to what should happen if this were to be a feature within the Cache system in Laravel. For example, as mentioned, protocols such as Memcached do not provide a way to retrieve the expiry time, so should the method exist, but return null? Or should it not exist at all?
Creating the method, but returning null, would mean you don't get an error when calling via the cache helper function:
cache()->remaining('my_key');
Not having the method would of course mean you receive an error.
Proposed usage
Get the expiry time as a human readable string
$expiry = cache()->remaining('my_key'); // "7 minutes from now"
Get the UNIX timestamp
$expiry = cache()->remaining('my_key', true); // 1720099976
What is wrong with two cache keys, one containing the data, the other the ttl?
Maybe it's better to return \DateIntrval object? We will be able to convert it to what format we want
What is wrong with two cache keys, one containing the data, the other the ttl?
I like it. But I feel like this is only necessary on protocols such as Memcached and Redis. Storing 2 keys for FileStore and DatabaseStore seems unnecessary to me as we can easily retrieve the expiration with these protocols for example, and would also make the expiration column somewhat redundant in the DatabaseStore cache table.
Retrieving an item from the cache could also have an optional parameter which enables the developer to also retrieve the remaining TTL for the given item in an array, such as:
[
'data' => ...,
'ttl' => 1720099976
]
So we could have 2 options to get the remaining TTL:
[$data, $ttl] = cache('my_data', ttl: true);
$ttl = cache()->remaining('my_data');
This is just quick drafting off the top of my head, so will test some implementations.
@Markshall please rebase this PR and mark it as ready if you need a new review.
Can we please fix tests on the local machine before pushing it?
Can we please fix tests on the local machine before pushing it?
Was having trouble replicating the tests on my local machine. I don't have memcached PHP extension installed so it's skipping the tests and trying to install it is proving impossible. Windows is saying the extension isn't found in my ext dir even though it clearly is there.