web-dev-qa-db-ja.com

ノードでRedis期限切れイベントを受信する方法は?

Redisからの期限切れイベントを聞きたいです。 redis.confnotify-keyspace-events "AKE"で構成しました。これは、ノード上のコードです。

const redis = require('redis');
const client = redis.createClient();
const subscriber = redis.createClient();
const KEY_EXPIRING_TIME = 10; // seconds

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!');
});

私が望んでいるのは、イベントがトリガーされることを10秒で確認することです。 setexコマンドは正しく機能します。10秒以内にキーがデータベースにありません。イベントをキャプチャしようとすると問題が発生します。

私は何が間違っているのですか?

10
emilioriosvz

実際、「期限切れ」タイプの キーイベント通知を聞くことは可能です 特定のチャネルにサブスクライブされたクライアントを使用します('__keyevent@db__:expired')そしてそのメッセージイベントを聞いています。

setInterval/setTimeoutまたは追加のライブラリは必要ありません

概念実証(動作: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)
}
19
EMX

アプローチ1:-

setInterval関数を使用して、値が定期的に期限切れになるかどうかを確認する必要があります。これはイベントを聞くことと同じではないことを私は知っています。ただし、間接的に目的を果たします。

以下のコードは、5秒ごとに値をチェックします。

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);

アプローチ2:-

redis-notifierは、イベントをリッスンするために使用できます。ただし、このパッケージをインストールするには、Python> = v2.5.0&<3.0.0が必要です。

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);
  }
});
6
notionquest