How to receive Redis expire events with node?

前端 未结 2 1826
Happy的楠姐
Happy的楠姐 2020-12-30 09:01

I want to listen the expire events from Redis. I\'ve configured on my redis.conf the notify-keyspace-events \"AKE\" and this is my code on node:

相关标签:
2条回答
  • 2020-12-30 09:12

    It is in fact possible to listen to the "expired" type keyevent notification using a subscribed client to the specific channel ('__keyevent@db__:expired') and listening to its message event.

    no need for setInterval / setTimeout or additional libraries

    Proof-of-concept (working : tested with NodeJS v.9.4.0)

    const redis = require('redis')
    const CONF = {db:3}
    var pub, sub
    //.: Activate "notify-keyspace-events" for expired type events
    pub = redis.createClient(CONF)
    pub.send_command('config', ['set','notify-keyspace-events','Ex'], SubscribeExpired)
    //.: Subscribe to the "notify-keyspace-events" channel used for expired type events
    function SubscribeExpired(e,r){
     sub = redis.createClient(CONF)
     const expired_subKey = '__keyevent@'+CONF.db+'__:expired'
     sub.subscribe(expired_subKey,function(){
      console.log(' [i] Subscribed to "'+expired_subKey+'" event channel : '+r)
      sub.on('message',function (chan,msg){console.log('[expired]',msg)})
      TestKey()
     })
    }
    //.: For example (create a key & set to expire in 10 seconds)
    function TestKey(){
     pub.set('testing','redis notify-keyspace-events : expired')
     pub.expire('testing',10)
    }
    
    0 讨论(0)
  • 2020-12-30 09:17

    Approach 1:-

    The setInterval function has to be used to check whether the value is expired periodically. I am aware that this is not equal to listening to events. However, it serves the purpose indirectly.

    The below code checks the value for every 5 seconds.

    const redis = require('redis');
    const client = redis.createClient();
    const subscriber = redis.createClient();
    const KEY_EXPIRING_TIME = 10; // seconds
    
    var args = ['myKey', KEY_EXPIRING_TIME,  'myValue'];
    
    
    client.setex('myKey', KEY_EXPIRING_TIME, 'myValue');
    
    subscriber.on('message', function(channel, msg) {
      console.log( `On ${channel} received ${msg} event`);
    });
    
    subscriber.subscribe('myKey', function (err) {
      console.log('subscribed!');
    });
    
    setInterval(function() {  
      client.get('myKey', function(err, value) {
        if (err) {
          throw err;
        }
        if (value) {
          console.log('value:', value);
        }
        else {
          console.log('value is gone');
          process.exit();
        }
      });
    }, 5e3);
    

    Approach 2:-

    The redis-notifier can be used to listen to the events. However, it requires Python >= v2.5.0 & < 3.0.0 in order to install this package.

    redis-notifier

    var RedisNotifier = require('redis-notifier');
    
    var eventNotifier = new RedisNotifier(redis, {
      redis : { host : '127.0.0.1', port : 6379 },
      expired : true,
      evicted : true,
      logLevel : 'DEBUG' //Defaults To INFO 
    });
    
    //Listen for event emission 
    eventNotifier.on('message', function(pattern, channelPattern, emittedKey) {
      var channel = this.parseMessageChannel(channelPattern);
      switch(channel.key) {
        case 'expired':
            this._handleExpired(emittedKey);
          break;
        case "evicted":
          this._handleEvicted(emittedKey);
          break;
        default:
          logger.debug("Unrecognized Channel Type:" + channel.type);
      }
    });
    
    0 讨论(0)
提交回复
热议问题