phplaravelredispredis

Redis keys are not expiring - Laravel, Predis


I am using Laravel 5.4, with Predis and the latest Redis (or Redis for Windows).

The keys are being saved without issue. So, I doubt it's a configuration issue.

The problem is that they are not expiring. The key is reused until it expires...similar to how a session works.

I create the key once, if it does not exist. In that same logic I then set the expiration time.

In the Controller, I have

use Illuminate\Support\Facades\Redis;

In one of the functions, Get the connection instance:

$redis = Redis::connection();

Before I create the key, I check the existence (simplified) then create and set expiration.

if(!$redis->exists($some_unique_key))
{
   //set the key
   $redis->set($some_unique_key, 'Some Value'));
   //set the expiration
   //I understand this means expire in 60s.
   $redis->expire($some_unique_key,60); 
}

Why could it not be expiring the key?

As I mentioned, everything else works. I see the key updating without issue if I monitor, and can query it.

For the record, I have read:

There is nothing on expiration on the Laravel documentation:

UPDATE 1

Investigating a possible cause where setting(updating) the key resets the expiry

UPDATE 2

Used @for_thestack's reasoning (in REDIS commands) to come up with the solution. See my answer with the code. Feel free to upvote @for_thestack :)


Solution

  • Some other process might call SET to update the key-value pair, in this case, the expiration will be removed.

    // set expiration
    EXPIRE key expiration_in_seconds
    // update key-value pair with no expiration
    SET key new_value
    // now, expiration has been reset, and the key won't be expired any more
    

    In order to keep the expiration, when you update the key-value pair, you should call SET with expiration parameters.

    // get TTL, i.e. how much time left before the key will be expired
    TTL key
    // update with expiration parameter
    SET key new_value EX ttl
    

    You can wrap the two commands into a lua script to make it atomic. And you also need to take care of the case that key doesn't exist when you call TTL. See the document for details.