@@ -7,6 +7,7 @@ import type * as storage from '@crawlee/types';
77import { s } from '@sapphire/shapeshift' ;
88import { move } from 'fs-extra' ;
99import mime from 'mime-types' ;
10+ import pLimit from 'p-limit' ;
1011
1112import { scheduleBackgroundTask } from '../background-handler' ;
1213import { maybeParseBody } from '../body-parser' ;
@@ -19,6 +20,7 @@ import { createKeyList, createKeyStringList, isBuffer, isStream } from '../utils
1920import { BaseClient } from './common/base-client' ;
2021
2122const DEFAULT_LOCAL_FILE_EXTENSION = 'bin' ;
23+ const GET_RECORD_CONCURRENCY = 25 ;
2224
2325export interface KeyValueStoreClientOptions {
2426 name ?: string ;
@@ -173,15 +175,15 @@ export class KeyValueStoreClient extends BaseClient {
173175
174176 const firstPageValuesPromise = ( async ( ) => {
175177 const firstPageKeys = await firstPageKeysPromise ;
176- const values : unknown [ ] = [ ] ;
177- for ( const item of firstPageKeys . items ) {
178- if ( limit !== undefined && values . length >= limit ) break ;
179- const record = await getRecord ( item . key ) ;
180- if ( record ) {
181- values . push ( record . value ) ;
182- }
183- }
184- return values ;
178+ const keysToFetch = limit !== undefined ? firstPageKeys . items . slice ( 0 , limit ) : firstPageKeys . items ;
179+ const limiter = pLimit ( GET_RECORD_CONCURRENCY ) ;
180+ const results = await Promise . allSettled ( keysToFetch . map ( ( item ) => limiter ( ( ) => getRecord ( item . key ) ) ) ) ;
181+ return results
182+ . filter (
183+ ( r ) : r is PromiseFulfilledResult < storage . KeyValueStoreRecord > =>
184+ r . status === 'fulfilled' && r . value !== undefined ,
185+ )
186+ . map ( ( r ) => r . value . value ) ;
185187 } ) ( ) ;
186188
187189 async function * asyncGenerator ( ) : AsyncGenerator < unknown > {
@@ -224,15 +226,19 @@ export class KeyValueStoreClient extends BaseClient {
224226
225227 const firstPageEntriesPromise = ( async ( ) => {
226228 const firstPageKeys = await firstPageKeysPromise ;
227- const entries : [ string , unknown ] [ ] = [ ] ;
228- for ( const item of firstPageKeys . items ) {
229- if ( limit !== undefined && entries . length >= limit ) break ;
230- const record = await getRecord ( item . key ) ;
231- if ( record ) {
232- entries . push ( [ item . key , record . value ] ) ;
233- }
234- }
235- return entries ;
229+ const keysToFetch = limit !== undefined ? firstPageKeys . items . slice ( 0 , limit ) : firstPageKeys . items ;
230+ const limiter = pLimit ( GET_RECORD_CONCURRENCY ) ;
231+ const results = await Promise . allSettled (
232+ keysToFetch . map ( ( item ) =>
233+ limiter ( ( ) => getRecord ( item . key ) . then ( ( record ) => ( { key : item . key , record } ) ) ) ,
234+ ) ,
235+ ) ;
236+ return results
237+ . filter (
238+ ( r ) : r is PromiseFulfilledResult < { key : string ; record : storage . KeyValueStoreRecord } > =>
239+ r . status === 'fulfilled' && r . value . record !== undefined ,
240+ )
241+ . map ( ( r ) => [ r . value . key , r . value . record . value ] as [ string , unknown ] ) ;
236242 } ) ( ) ;
237243
238244 async function * asyncGenerator ( ) : AsyncGenerator < [ string , unknown ] > {
0 commit comments