我试图从我的redis示例中一次检索N个键。在本例中,我将N个键指定为batchSize = 100
。这段代码似乎无限循环,这表明我没有正确地将光标取回。输出无限循环:我的测试数据库中总共有719个键,所以理论上应该在retrieveLogs
上循环8次,7批100个,1批19个。
我找不到关于如何正确使用它的文档,但这是我的整个程序。有什么地方我做错了吗?
/* eslint-disable no-await-in-loop */
/* eslint-disable no-restricted-syntax */
import { createClient } from 'redis';
const redisClient = createClient({ url: process.env.REDIS_URL });
redisClient.on('error', (err) => {
console.log('Redis Client Error', err);
throw new Error('Redis Client Error');
});
async function retrieveLogs(batchSize) {
const logs = [];
for await (const cursor of redisClient.scanIterator({
MATCH: 'log:*',
COUNT: batchSize,
})) {
const log = await redisClient.get(cursor);
if (log) {
logs.push(JSON.parse(log));
}
if (cursor === '0') {
console.log('breaking');
break;
}
}
return logs;
}
async function main() {
redisClient.on('error', (err) => {
console.log('Redis Client Error', err);
throw new Error('Redis Client Error');
});
await redisClient.connect();
// Set the number of logs to retrieve and delete at a time
const batchSize = 100;
// Set a flag to indicate whether there are more logs to process
let moreLogs = true;
while (moreLogs) {
// Retrieve a batch of logs from Redis
// eslint-disable-next-line no-await-in-loop
const batch = await retrieveLogs(batchSize);
if (batch.length === 0) {
// If there are no logs, set the flag to false to exit the loop
moreLogs = false;
break;
}
console.log(`got a batch of ${batch.length} logs`);
}
await redisClient.disconnect();
}
main();
1条答案
按热度按时间jvlzgdj91#
主要的问题是,您收集了所有对
retrieveLogs()
的**调用的结果,而main()
中的while
循环似乎准备在每次调用时接受一个项目块。因为异步迭代器scanIterator()
返回已经允许消耗所有SCAN
结果-隐藏了异步迭代器本身的复杂性。因此,要解决这个问题,您可以删除
main()
中的while
循环,或者查看逻辑,以便在main()
中迭代对scanIterator()
的调用结果。另外,
scanIterator()
返回键而不是游标,因为实际的游标隐藏在异步迭代器实现中,所以异步迭代中的短路逻辑应该被删除,您可能还需要相应地重命名该变量:而且......
scanIterator()
返回的键肯定存在,因此您 * 甚至可以 *(取决于您的解析逻辑)删除对log
的额外真实性检查。