Skip to content

feat(storage): support pre-warming read ranges in AsyncConnection - #16275

Open
kalragauri wants to merge 3 commits into
googleapis:mainfrom
kalragauri:feat/fast-open
Open

feat(storage): support pre-warming read ranges in AsyncConnection#16275
kalragauri wants to merge 3 commits into
googleapis:mainfrom
kalragauri:feat/fast-open

Conversation

@kalragauri

Copy link
Copy Markdown
Contributor

This PR implements the backend plumbing and happy-path caching to support pre-warming read ranges in the GCS async client.

Key changes:

  • Introduced ReadRangesOption containing a list of ReadRangeConfig (offset and length) to configure which ranges to pre-warm.
  • Updated AsyncConnectionImpl::Open to populate the initial BidiReadObjectRequest with the configured read_ranges.
  • Updated ObjectDescriptorImpl constructor to initialize ReadRange objects for pre-warmed ranges and register them on the initial stream so incoming GCS data chunks are routed correctly and not discarded.
  • Implemented a prewarmed_ranges_ cache in ObjectDescriptorImpl. When the user calls Read(), the cache is checked. On a hit, the pre-warmed ReadRange is claimed and returned as an ObjectDescriptorReader.

@product-auto-label product-auto-label Bot added the api: storage Issues related to the Cloud Storage API. label Jul 27, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request introduces support for pre-warmed ranges in the asynchronous GCS client, allowing specified ranges to be downloaded as soon as a stream opens. It adds the ReadRangesOption configuration, updates AsyncConnectionImpl::Open to populate the initial request with these ranges, and modifies ObjectDescriptorImpl to cache and claim them during reads. The feedback suggests critical improvements to the caching mechanism: using std::multimap instead of std::map to prevent resource leaks when duplicate ranges are configured, using emplace for insertion, and utilizing std::move to avoid unnecessary copies of std::shared_ptr when claiming cached ranges.

Comment thread google/cloud/storage/internal/async/object_descriptor_impl.h
Comment thread google/cloud/storage/internal/async/object_descriptor_impl.cc Outdated
Comment thread google/cloud/storage/internal/async/object_descriptor_impl.cc Outdated
@kalragauri
kalragauri marked this pull request as ready for review July 27, 2026 08:51
@kalragauri
kalragauri requested review from a team as code owners July 27, 2026 08:51
// If pre-warmed ranges are configured, populate the initial request
// with these ranges to start downloading them as soon as the stream opens.
if (current->has<ReadRangesOption>()) {
auto const& ranges = current->get<ReadRangesOption>();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This exact same ID generation and deduplication loop is copied in both connection_impl.cc and object_descriptor_impl.cc. If someone updates the logic in one file and forgets the other, the read_ids won't match and data will be sent to the wrong ranges. Should we move this logic into a single shared helper function?

if (it != stream_manager_->End()) {
std::int64_t id = 0;
std::set<std::pair<std::int64_t, std::int64_t>> seen_ranges;
for (auto const& r : ranges) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

same as above

// these ranges.
it->active_ranges.emplace(id, range);
// Cache them so subsequent `Read()` calls can claim them.
prewarmed_ranges_.emplace(range_key, PrewarmedRange{range, id});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

What would happen if the user configures pre-warmed ranges but their application never actually calls Read() to claim them?

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

Labels

api: storage Issues related to the Cloud Storage API.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants