Preserving TTL for redis item update


When you update an item in Redis, there's no real difference than setting it for the first time. That means that the expire time (TTL) on the original record will be lost, but if you are updating you may want to retain the value to where it's at now. I originally posted this on stackoverflow but I'm also posting it here in case you find it useful

Expiring in Redis

If you are using the ioredis client API, then you can set a value and its expire time in the same call, like this
redis.set (key , value , "EX" , expiretimeinseconds);

if you just do this, the item won't expire. 
redis.set(key, value)

But in this example, I want to set the expire time to whatever it currently is. The expire time can be retrieved like this
redis.ttl(key)

Putting it all together

As usual, I'm using Promises, and also I'll stringify the content if it comes over as an object.

the optional expire argument can take these values
>0  - use as the new expire time for the item
0  - use the existing TTL as the expire time. If there is no expire time, or the item doesn't exist there will be no expiry
undefined - no expiry

 /**
       * update an item. preserve ttl or set a new one
       * @param {object} handle the redis handle
       * @param {string} key the key
       * @param {*} content the content - if an object it'll get stringified
       * @param {number||null} [expire] if a number > 0 its an expire time, 0 means keep existing ttl, undefined means no expiry
       * @return {Promise}
       */
      ns.updateItem = function (handle , key , content,expire) {

        // first we have to get the expiry time if needed
        return (expire === 0 ? handle.ttl(key) : Promise.resolve (expire))
        .then (function (e) {

          // deal with errors retrieving the ttl (-1 no expiry, -2 no existing record)
          var ttl = e > 0 ? e :  undefined;

          // stingify the data if needed
          var data = typeof content === "object" ? JSON.stringify(content) : content;

          // set and apply ttl if needed
          return ttl ? handle.set (key, data , "EX", ttl) : handle.set (key,data);
        });
      };

So to update an objecy and retain the current TTL :-
namespace.updateItem (handle , key , content, 0).then ((result)=>{ // do something // });






For more like this, see React, redux, redis, material-UI and firebase. Why not join our forum, follow the blog or follow me on twitter to ensure you get updates when they are available.
Comments