1
0
mirror of https://github.com/redis/node-redis.git synced 2025-08-06 02:15:48 +03:00

ref #2370 add support for CommandIterator in ScanIterator

Co-authored-by: Leibale Eidelman <me@leibale.com>
This commit is contained in:
shacharPash
2023-01-19 19:13:27 +02:00
parent abf2b4bc82
commit bf272742e4
3 changed files with 76 additions and 21 deletions

View File

@@ -607,24 +607,48 @@ describe('Client', () => {
return client.executeIsolated(isolated => killClient(isolated, client));
}, GLOBAL.SERVERS.OPEN);
testUtils.testWithClient('scanIterator', async client => {
const promises = [],
keys = new Set();
for (let i = 0; i < 100; i++) {
const key = i.toString();
keys.add(key);
promises.push(client.set(key, ''));
}
describe('scanIterator', () => {
testUtils.testWithClient('strings', async client => {
const args: Array<string> = [],
keys = new Set<string>();
for (let i = 0; i < 100; i++) {
const key = i.toString();
args.push(key, '');
keys.add(key);
}
await Promise.all(promises);
await client.mSet(args);
const results = new Set();
for await (const key of client.scanIterator()) {
results.add(key);
}
const results = new Set<string>();
for await (const key of client.scanIterator()) {
results.add(key);
}
assert.deepEqual(keys, results);
}, GLOBAL.SERVERS.OPEN);
assert.deepEqual(keys, results);
}, GLOBAL.SERVERS.OPEN);
testUtils.testWithClient('buffers', async client => {
const args: Array<string | Buffer> = [],
keys = new Set<Buffer>();
for (let i = 0; i < 100; i++) {
const key = Buffer.from([i]);
args.push(key, '');
keys.add(key);
}
await client.mSet(args);
const results = new Set<Buffer>(),
iteartor = client.scanIterator(
client.commandOptions({ returnBuffers: true })
);
for await (const key of iteartor) {
results.add(key);
}
assert.deepEqual(keys, results);
}, GLOBAL.SERVERS.OPEN);
});
testUtils.testWithClient('hScanIterator', async client => {
const hash: Record<string, string> = {};

View File

@@ -656,10 +656,29 @@ export default class RedisClient<
return results;
}
async* scanIterator(options?: ScanCommandOptions): AsyncIterable<string> {
scanIterator<T extends CommandOptions<ClientCommandOptions>>(
commandOptions: T,
options?: ScanCommandOptions
): AsyncIterable<T['returnBuffers'] extends true ? Buffer : string>;
scanIterator(
options?: ScanCommandOptions
): AsyncIterable<string>;
async* scanIterator<T extends CommandOptions<ClientCommandOptions>>(
commandOptions?: T | ScanCommandOptions,
options?: ScanCommandOptions
): AsyncIterable<T['returnBuffers'] extends true ? Buffer : string> {
if (!isCommandOptions(commandOptions)) {
options = commandOptions;
commandOptions = undefined;
}
const scan = commandOptions ?
(...args: Array<unknown>) => (this as any).scan(commandOptions, ...args) :
(...args: Array<unknown>) => (this as any).scan(...args);
let cursor = 0;
do {
const reply = await (this as any).scan(cursor, options);
const reply = await scan(cursor, options);
cursor = reply.cursor;
for (const key of reply.keys) {
yield key;
@@ -726,3 +745,15 @@ attachCommands({
executor: RedisClient.prototype.commandsExecutor
});
(RedisClient.prototype as any).Multi = RedisClientMultiCommand;
const client = RedisClient.create();
const a = client.scanIterator(
client.commandOptions({returnBuffers: true})
)
const b = client.scanIterator(
client.commandOptions({returnBuffers: false})
)
const c = client.scanIterator()

View File

@@ -52,7 +52,7 @@ const DOCKER_FODLER_PATH = path.join(__dirname, '../docker');
async function spawnRedisServerDocker({ image, version }: RedisServerDockerConfig, serverArguments: Array<string>): Promise<RedisServerDocker> {
const port = (await portIterator.next()).value,
{ stdout, stderr } = await execAsync(
'docker run -d --network host $(' +
`docker run -d -p ${port}:${port} $(` +
`docker build ${DOCKER_FODLER_PATH} -q ` +
`--build-arg IMAGE=${image}:${version} ` +
`--build-arg REDIS_ARGUMENTS="--save '' --port ${port.toString()} ${serverArguments.join(' ')}"` +