You can use keyspace events to listen for key expiring events, you need two distinct channels one for publishing events (main channel) and another one to listen for expiring events, the default behavior of Redis is to only return the key of the element that expired in the expiring event message, a workaround this can be found here, the following is a simple implementation using that workaround:
import Redis from 'ioredis';
const subscribeChannel = new Redis({
host: 'localhost',
port: '6379',
db: 0,
});
const publishChannel = new Redis({
host: 'localhost',
port: '6379',
db: 0,
});
function set(channel, key, value, seconds){
channel.set(key, value);
// use shadowkey to access the value field on the expire event message
channel.set(`${key}:${value}`, '');
// set expire time on shadowkey
channel.expire(`${key}:${value}`, seconds);
}
publishChannel.on('ready', () => {
// configure keyspaces event and specify expiring events with "Ex"
publishChannel.config("SET", "notify-keyspace-events", "Ex");
// subscribe to the
subscribeChannel.subscribe("__keyevent@0__:expired");
// listen for expiring event messages
subscribeChannel.on('message', async(channel, message) => {
// retrieve key and value from shadowkey
const [key, value] = message.split(":");
// store value in the main storage
db.insert(value);
// delete actual value from the redis store
publishChannel.del(key);
});
// set "value" with "key" and set it to expire after 10 seconds
set(publishChannel, "key", "value", 10);
});