'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 |
---|