Redis 客户端 - on('ready') 事件

Redis client - on('ready') event

我正在为 Node.js 使用 Redis NPM 库 - 我可以像这样监听连接 'ready' 事件

var client = require('redis').createClient();

client.on('ready', function () {
    client.keys('*', function (err, keys) {
        if (err) {
            log.error(err);
        } else {
            for (var i = 0; i < keys.length; i++) {
                createLocalDataMap(keys[i]);
            }
        }
    });
});

但是,我如何查询 Redis 以查看它是否准备就绪,而不是在我准备好处理之前监听可能会触发的事件?

我想我可以放弃 ready 事件,只做一个查询,然后等待响应,但是有没有更好、更安全、更复杂的方法?

换句话说,我很可能不得不编写这样的函数:

var isReady = false;

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

      isReady = true;
});

function doSomethingMuchLater(){

if(isReady){

     //query redis as normal
}
else {

   client.on('ready', function(){
   isReady = true;
     //now I do what I wanted to do
   });

}
}

这似乎根本不对,一定有更好的方法

node-redis 客户端会在连接准备好之前自动对您发送的任何命令进行排队。连接后,这些命令都会在 .on('ready') 触发之前发送。因此,您真的不需要使用 .on('ready')。如果您过早发送命令,它们仍会按预期进行,如果您的连接完全失败,它们将永远不会被发送。

即使命令已排队,我还是遇到了一些讨厌的日志记录错误,因为我在数据库未完全加载时发送命令。 connect 事件还不够。

来自文档:

[options.enableReadyCheck] boolean

When a connection is established to the Redis server, the server might still be loading the database from disk. While loading, the server not respond to any commands. To work around this, when this option is true, ioredis will check the status of the Redis server, and when the Redis server is able to process commands, a ready event will be emitted.

所以这是我让它可靠工作的唯一方法是使用 ioredis 库:

import Redis from 'ioredis';

class RedisClient {
  private static instance: Redis.Redis | undefined;
  private redisUrl: string;
  private options?: Redis.RedisOptions;

  private constructor(
    redisUrl?: string,
    options?: Redis.RedisOptions,
  ) {
    this.redisUrl = redisUrl || `redis://${REDIS.HOST}:${REDIS.PORT}`;
    this.options = options;
  }

  static async init(
    redisUrl?: string,
    options?: Redis.RedisOptions,
  ): Promise<RedisClient | undefined> {
    try {
      RedisClient.instance = new Redis(RedisClient.redisUrl, {
        ...options,
        enableReadyCheck: true,
      });
      const onReady = (): Promise<boolean> => new Promise((resolve) => {
        (RedisClient.instance as Redis.Redis).on('ready', () => {
          resolve(true);
          infoLogger.info('Redis server online...');
        });
      });
      await onReady();
      return new RedisClient(redisUrl, {
        ...options,
        enableReadyCheck: true
      });
    } catch (err) {
      new ServerError({
        message: 'Redis client init error.',
        internalCode: ErrorCodes.cacheInitError,
        internal: true,
      }).log();

      if (RedisClient.instance) RedisClient.instance.quit();
      return undefined;
    }
  }

  async get(key: string): Promise<someType> {
    ...
  }

  async set<T extends Record<string, unknown>>(key: string, value: Stringified<T> | string): Promise<void> {
    ...
  }

  async del(key: string): Promise<void> {
    ...
  }

  async flush(): Promise<void> {
    ...
  }
}

import RedisClient from 'somewhere';

const redis = await RedisClient.init();