'Problem with scanning and removing keys in redis after updating package version to 4.0.4

After updating redis from version 3.1.2 to 4.0.4, the method that removes keys from the database stopped working in my redis class.

In the scanDel method, the scanAsync method is called, in the callback of which the iteration of keys and deletion is already taking place.

The scanAsync method itself contains the recursive function recursiveScan for searching for keys, the problem is that it cannot find the keys and I don’t understand why (I didn’t write the code, so I only partially understand what is going on there).

If you find it difficult to understand what is at stake, then I hope that the code will become a little clearer.

class RedisClientFront {
  constructor() {
    // always simple, just default client creation and connecting
    this.client = config.REDIS_CLUSTER !== 'true' ? simple(redisOptions) : cluster(redisOptions);
    this._del = this.client.del.bind(this.client);

    async () => {
      await this.client.connect();
    };
  }

  async del(key) {
    return this._del(key);
  }

  async scanAsync(pattern, options, callback) {
    const method = options.method || 'scan';
    const key = options.key || '';
    const count = options.count || 0;
    const type = options.type || '';
    const limit = options.limit || Infinity;
    let matchesCount = 0;
    const recursiveScan = (redisClient, startCursor = 0) =>
      new Promise((resolve, reject) => {
        const parameters = key
          ? [key, startCursor, 'MATCH', pattern]
          : [startCursor, 'MATCH', pattern];

        if (count > 0) {
          parameters.push('COUNT', count);
        }

        if (type) {
          parameters.push('TYPE', type);
        }
        redisClient[method](...parameters, (err, data) => {
          if (err) {
            reject(err);
          } else {
            const [cursor, matches] = data;
            matchesCount += matches.length;
            callback(matches);
            if (cursor === '0' || matchesCount >= limit) {
              resolve(matchesCount);
            } else {
              recursiveScan(redisClient, cursor).then(resolve);
            }
          }
        });
      });

    if (this.client.connections) {
      const asyncTask = [];
      // eslint-disable-next-line
      for (const connection in this.client.connections) {
        if (this.client.connections[connection]) {
          asyncTask.push(recursiveScan(this.client.connections[connection], 0, connection));
        }
      }

      await Promise.all(asyncTask);
    } else {
      await recursiveScan(this.client);
    }
  }

  scanDel(pattern, not = false) {
    this.scanAsync(pattern, { count: 10 }, (keys) => {
      logger.info('hey');
      for (let i = 0; i < keys.length; i++) {
        const key = keys[i];
        if (!not || not.every((el) => key.indexOf(el) === -1)) {
          this.del(key);
          logger.info('hey');
        }
      }
    });
  }
}

I call the function with these parameters

scanDel('dev_cache:*')

I am sure that the problem is in synchronism, promises that have been added in the new version.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source