Node-redis: retornar Erro de retry_strategy não emite no evento (erro)

Criado em 21 jul. 2016  ·  10Comentários  ·  Fonte: NodeRedis/node-redis

  • Versão : nó 4.2.1, redis 2.6.2
  • Plataforma : Mac OS 10.11.5
  • Descrição :

Implementamos um retry_strategy que emite um erro após uma certa quantidade de tentativas. Isso então faria um balão para o manipulador on ('erro') do Redis ser registrado e sair do aplicativo. Ao atualizar nossa biblioteca redis de 2.4.2 para 2.6.2 , notamos que esse comportamento não é mais o mesmo.

Caso Repro:

const redis = require('redis');
const MAX_ATTEMPTS = 10;
var client = redis.createClient(port, host, { 
  retry_strategy: redisRetryStrategy
});
client.on('error', onError);

function OnError(err) {
  console.log(err);
  throw new Error('SHUTDOWN THE APP, REDIS IS NOT RESPONDING??');
}

function redisRetryStrategy(host, options) {
  if (options.attempt >= MAX_ATTEMPTS) {
    // Stop reconnecting after reaching the maximum number of attempts
    return new Error('Maximum redis reconnect attempts reached');
  }
  return 1000; // Schedule next reconnection attempt after 1 sec.
}

Comentários muito úteis

Sim: borbulhe o erro para o listener de erro

Todos 10 comentários

Na verdade, isso foi feito de propósito. A razão é que você já tem a informação de que o cliente falhou, então não precisa mais ser emitida. Esta não é, de fato, uma boa mudança em relação a manter o semver acordado: / Sinto muito por isso.

Eu gostaria de fazer uma pequena enquete para ver o que outras pessoas estão pensando. Ping @ NodeRedis / contributors @dirkbonhomme

Sim: borbulhe o erro para o listener de erro

Não: mantenha a solução atual

Apenas para oferecer um caso de uso em favor do anterior, o connect-redis fornece uma opção logErrors que se torna (não obviamente) mutuamente exclusiva com retry_strategy se os erros não surgirem.

new RedisStore({
  logErrors: (err) => console.error, // does nothing
  retry_strategy: (options) => {
    if (options.error.code === 'ECONNREFUSED' || options.error.code === 'ENOTFOUND') {
      return new Error('The server could not be found or refused the connection');
    }
    return 1000;
  }
})

@tj

Acho que a funcionalidade atual está bem, contanto que esteja na documentação, o que não está. Acho que também seria aceitável adicionar uma opção que ainda gerasse erros retornados da estratégia de nova tentativa.
Ex.:

redis.createClient({
    retry_strategy: ...,
    retry_strategy_bubble_up: true or false (default to false to keep existing functionality)
});

Passei o último dia tentando descobrir por que os erros não estavam sendo registrados. Agora que o registro está no retorno de chamada retry_strategy, tudo está como eu quero em meu aplicativo.

Em vez de lançar o erro, estou emitindo manualmente o evento de erro que pode ser detectado pelo manipulador de erros:

retry_strategy: function(options) {
            logger.debug('Retry redis connection: ', options.attempt);

            // 5 mins
            if (options.total_retry_time > 1000 * 60 * 5) {
                // End reconnecting after a specific timeout and flush all commands with a individual error
                return logger.error('Redis: maximum retry time exhausted');
            }
            if (options.attempt > 5) {
                // End reconnecting with built in error
                logger.error('Redis: maximum connection retry reached');
                return client.emit('error', 'maximum retry');
            }
            return 1000 * 2;
        },

Bubble up! (ou outra coisa)

O emissor de erro customizado como @alannesta escreveu é bagunçado, retry_strategy é um dos parâmetros do construtor, ele não deve acessar objetos que estejam fora da função.

NodeRedis já tinha um sistema de eventos, basta usá-lo!

Como end foi retirado e significa "conexão encerrada", podemos adicionar um novo evento (vamos chamá-lo de "desligamento" por enquanto) indicando "fizemos tudo o que podíamos, esta conexão morreu , a partir de agora não faremos nada sobre isso, é melhor vocês fazerem uns trabalhos de limpeza ”.

Eu realmente preciso dessa mudança.

Aconteceu alguma coisa com esse problema?

Existe uma razão para isso não ser corrigido ou apenas prioritário? Qual é a vantagem de não emitir o evento? Não existe uma maneira óbvia de encerrar um serviço sem mais conexão redis funcional ao usar retry_strategy e esse deve ser um caso de uso bastante básico. A melhor solução, entretanto, provavelmente seria um evento separado, como @AaronJan sugeriu.

Eu lancei a v3.0.0 que agora borbulha qualquer erro retornado de retry_strategy até o ouvinte de evento error .

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

adamgajzlerowicz picture adamgajzlerowicz  ·  4Comentários

ghost picture ghost  ·  3Comentários

gpascale picture gpascale  ·  4Comentários

lemon707 picture lemon707  ·  3Comentários

strumwolf picture strumwolf  ·  4Comentários