Skip to content

fix: change sequential approach to parallel for Iterator first page#3402

Merged
l2ysho merged 2 commits into
masterfrom
3395-review-double-fetch-in-kvm-iterators
Feb 12, 2026
Merged

fix: change sequential approach to parallel for Iterator first page#3402
l2ysho merged 2 commits into
masterfrom
3395-review-double-fetch-in-kvm-iterators

Conversation

@l2ysho
Copy link
Copy Markdown
Contributor

@l2ysho l2ysho commented Feb 11, 2026

Batch concurrent record fetching in KVS values() and entries() Promise path

Summary

The values() and entries() methods on KeyValueStoreClient previously fetched records sequentially in their eager Promise path (used when callers await the result directly). For stores with many keys, this meant each getRecord() call blocked before the next could start. This change replaces the sequential loop with Promise.allSettled gated by p-limit (concurrency of 25), fetching records in parallel while preserving order and gracefully skipping missing keys.

closes #3395

@l2ysho l2ysho requested review from B4nan and barjin February 11, 2026 12:45
@l2ysho l2ysho self-assigned this Feb 11, 2026
@l2ysho l2ysho added the t-tooling Issues with this label are in the ownership of the tooling team. label Feb 11, 2026
@l2ysho l2ysho linked an issue Feb 11, 2026 that may be closed by this pull request
@github-actions github-actions Bot added this to the 134th sprint - Tooling team milestone Feb 11, 2026
@l2ysho
Copy link
Copy Markdown
Contributor Author

l2ysho commented Feb 11, 2026

Quick PR to address our discussion in issue. I introduced GET_RECORD_CONCURRENCY constant, can someone suggest a safe value for concurency for getRecords? (25 now) @barjin @B4nan

@B4nan
Copy link
Copy Markdown
Member

B4nan commented Feb 11, 2026

can someone suggest a safe value for concurency for getRecords?

25 sounds all right to me. But if you wanna be safe, you can ask someone from other teams on slack I guess.

@B4nan
Copy link
Copy Markdown
Member

B4nan commented Feb 11, 2026

Now I see you used this only in the memory storage, in that case 25 sounds all right and it makes no sense to raise this on slack, since we are not firing any API requests at all, right?

@l2ysho
Copy link
Copy Markdown
Contributor Author

l2ysho commented Feb 11, 2026

Now I see you used this only in the memory storage, in that case 25 sounds all right and it makes no sense to raise this on slack, since we are not firing any API requests at all, right?

true 👍

Copy link
Copy Markdown
Member

@barjin barjin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks pretty straightforward, thank you @l2ysho !

One note: this doesn't (fully) solve #3395, as the iterator still waits for the full page to be loaded before yielding the first item. This is what I'm describing in #3395 (comment).

Nonetheless, this is a step forward. 👍

const limiter = pLimit(GET_RECORD_CONCURRENCY);
const results = await Promise.allSettled(
keysToFetch.map((item) =>
limiter(() => getRecord(item.key).then((record) => ({ key: item.key, record }))),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: record is { key:string, value: any } already, maybe you can just pass record here?

export interface KeyValueStoreRecord {
key: string;
value: any;
contentType?: string;

@l2ysho
Copy link
Copy Markdown
Contributor Author

l2ysho commented Feb 12, 2026

Looks pretty straightforward, thank you @l2ysho !

One note: this doesn't (fully) solve #3395, as the iterator still waits for the full page to be loaded before yielding the first item. This is what I'm describing in #3395 (comment).

Nonetheless, this is a step forward. 👍

yop, I should get rid of IEFF and figure out some lazy loading for the first page 🤔

const result = {
    then(resolve: any, reject: any) {
        return getFirstPageEntries().then(resolve, reject);
    },
    [Symbol.asyncIterator]: asyncGenerator,
};

But it started to be complex to read even without this. I will merge this as is and we can iterate it later.

@l2ysho l2ysho merged commit adf3dae into master Feb 12, 2026
9 checks passed
@l2ysho l2ysho deleted the 3395-review-double-fetch-in-kvm-iterators branch February 12, 2026 08:47
@barjin
Copy link
Copy Markdown
Member

barjin commented Feb 12, 2026

we can iterate later

Agreed, please make/reopen an issue for that (the original one got closed by this PR).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

t-tooling Issues with this label are in the ownership of the tooling team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Review double fetch in KVS iterators

4 participants