EXPIRE Redis ключ, если не изменен

Есть ли простой способ ИСКЛЮЧИТЬ КЛЮЧ Redis, если значение не было изменено за последние x минут?

Я сомневаюсь, что это возможно, но мне интересно, есть ли собственное решение или что-то с очень небольшой логикой и / или дополнительным состоянием.

Такое поведение может уже присутствовать - я вызываю EXPIRE для клавиши. Затем, если я вызываю SET для этого ключа, я могу снова вызвать EXPIRE, и ключ будет EXPIRE с новым значением, а не старым?


person Alexander Mills    schedule 04.02.2016    source источник
comment
У меня такой же сценарий, поэтому я сделал, как вы сказали. Всякий раз, когда я обращаюсь к ключу, я продлеваю срок его действия с новым значением ... Вот оно и есть.   -  person Nebras    schedule 05.02.2016


Ответы (1)


Ваше предположение верно, просто истекает одно за другим.

EXPIRE не накапливается, не сбрасывается или что-то еще, он просто устанавливает таймер на новое значение.

Пример (без обработки ошибок для многословия):

'use strict';

let client = require('redis').createClient()
const KEY = 'my:key';
const TTL = 10;
let value = 'some-value';

client.on('ready', function() {

  console.log('Setting key...')
  client.set(KEY, value, function() {

    console.log('Setting expire on the key...');
    client.expire(KEY, TTL, function() {

      console.log('Waiting 6 sec before checking expire time...');
      // Check in 6 seconds, ttl should be around 6
      setTimeout(function() {

        client.ttl(KEY, function(err, expiryTime) {

          console.log('expiryTime:', expiryTime); // "expiryTime: 6" on my system
          // expire again to show it does not stack, it only resets the expire value

          console.log('Expiring key again...');
          client.expire(KEY, TTL, function() {

            // again wait for 3 sec
            console.log('Waiting 3 more sec before checking expire time...');
            setTimeout(function() {

              client.ttl(KEY, function(err, expiryTime) {

                console.log('New expiryTime:', expiryTime); // 7
                process.exit();
              })
            }, 3000);
          });
        });
      }, 6000);
    });
  });
});

(Извините за пирамиду обратного вызова).

Запускаем это в моей системе:

[zlatko@desktop-mint ~/tmp]$ node test.js
Setting key...
Setting expire on the key...
Waiting 6 sec before checking expire time...
expiryTime: 4
Expiring key again...
Waiting 3 more sec before checking expire time...
New expiryTime: 7
[zlatko@desktop-mint ~/tmp]$ 

Как видите, мы установили время истечения 10 секунд. Через 6 секунд, очевидно, осталось 4 секунды.

Если мы в этот момент, за 4 секунды до конца, снова установим expire на 10, мы просто начнем с 10. Через 3 секунды после этого у нас все еще будет хорошо еще 7 секунд.

person Zlatko    schedule 04.02.2016
comment
Спасибо, из документации Redis Тайм-аут будет очищен только командами, которые удаляют или перезаписывают содержимое ключа, включая DEL, SET, GETSET и все команды * STORE ... Так что, похоже, мне нужно быть осторожным при вызове EXPIRE после вызова SET, а не наоборот. Однако, если SET всегда очищает тайм-аут, тогда в документации об этом не говорится ... Я думаю, мне нужно знать, всегда ли SET очищает тайм-аут. - person Alexander Mills; 04.02.2016
comment
Да, но вы также можете использовать setex, который устанавливает и истекает срок действия ключа атомарно. - person Zlatko; 05.02.2016
comment
Кроме того, SET не очищает тайм-аут. Просто добавляет новое значение к ключу, который потенциально существует с необязательным тайм-аутом ранее. - person Zlatko; 05.02.2016