Reputation: 1169
In my Nodejs app, I use a library that sets keys in my Redis database. So, I need to listen to every request that creates/updates a key and add a ttl
on every key (whether it already exists or not).
I have my main Redis client (that add keys to the Redis database) :
const redisClient = createClient({
url: redisUrl,
tls: {
ca: Buffer.from(redisCertBase64, 'base64').toString('utf-8'),
},
})
And I have added another client that should listen to set
events :
const subscriberRedis = redisClient.duplicate()
function done(err) {
logger.error('Notifications not active')
if (err) {
logger.error(err.stack || err.message || err)
}
}
const eventType = 'notify-keyspace-events'
subscriberRedis.config('get', eventType, (err, conf) => {
if (err) {
logger.debug('subscriberRedis:get =>', err.message)
return done(err)
}
logger.debug('conf =>', conf)
if (conf[1].indexOf('EKx') < 0) {
subscriberRedis.config('set', eventType, conf[1] + 'EKx', function (err) {
if (err) {
logger.debug('subscriberRedis:set =>', err.message)
return done(err)
}
})
}
})
const EVENT_SET = '__keyevent@0__:set'
subscriberRedis.on('message', function (channel, key) {
switch (channel) {
case EVENT_SET:
logger.info('Key "' + key + '" set!')
break
}
})
subscriberRedis.subscribe(EVENT_SET)
When I run this code, I get in the logs subscriberRedis:set => ERR only (P)SUBSCRIBE / (P)UNSUBSCRIBE / PING / QUIT allowed in this context
which is logged by the subscriberRedis.config('set',...)
I'm not sure what I'm missing here.
EDIT
I changed the code to this, and it's working now. However, do you think the "race condition" issue is still there when I move to production ?
const redisClient = createClient({
url: redisUrl,
tls: {
ca: Buffer.from(redisCertBase64, 'base64').toString('utf-8'),
},
})
/**
* Subscriber listening to `set` events
**/
const subscriber = redisClient.duplicate()
const EVENT_SET = '__keyevent@0__:set'
subscriber.on('message', function (channel, key) {
switch (channel) {
case EVENT_SET:
redisClient.expire(key, 300)
logger.debug('Key "'.red + key + '" set!'.yellow)
break
}
})
subscriber.subscribe(EVENT_SET)
Upvotes: 1
Views: 1331
Reputation: 9568
The problem is that by the time you call subscriberRedis.config('set'
your subscriberRedis has already subscribed on subscriberRedis.subscribe(EVENT_SET)
.
And, you can't use this connection for subscriberRedis.config('set'
while you are subscribed.
Upvotes: 1