Redis Node для прослушивания событий SET и установки TTL для каждого запроса - PullRequest
0 голосов
/ 21 апреля 2020

В моем приложении Nodejs я использую библиотеку, которая устанавливает ключи в моей базе данных Redis. Поэтому мне нужно прослушивать каждый запрос, который создает / обновляет ключ, и добавлять ttl к каждому ключу (независимо от того, существует он или нет).

У меня есть основной клиент Redis (который добавляет ключи к база данных Redis):

const redisClient = createClient({
    url: redisUrl,
    tls: {
        ca: Buffer.from(redisCertBase64, 'base64').toString('utf-8'),
    },
})

И я добавил еще одного клиента, который должен прослушивать set события:

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)

Когда я запускаю этот код, я получаю в журналах subscriberRedis:set => ERR only (P)SUBSCRIBE / (P)UNSUBSCRIBE / PING / QUIT allowed in this context, который регистрируется subscriberRedis.config('set',...)

Я не уверен, что мне здесь не хватает.

РЕДАКТИРОВАТЬ

Я изменил код для этого, и он работает сейчас. Однако, как вы думаете, проблема «состояния гонки» все еще остается, когда я перехожу на производство?

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)

1 Ответ

0 голосов
/ 21 апреля 2020

Проблема в том, что к тому времени, когда вы звоните subscriberRedis.config('set', ваш subscriberRedis уже подписан на subscriberRedis.subscribe(EVENT_SET).

И вы не можете использовать это соединение для subscriberRedis.config('set', пока вы подписаны.

...