Skip to content

readyreader: add buffered reader#9055

Merged
arjan-bal merged 5 commits into
grpc:masterfrom
arjan-bal:buf-ready-reader
Apr 16, 2026
Merged

readyreader: add buffered reader#9055
arjan-bal merged 5 commits into
grpc:masterfrom
arjan-bal:buf-ready-reader

Conversation

@arjan-bal

@arjan-bal arjan-bal commented Apr 10, 2026

Copy link
Copy Markdown
Contributor

This PR introduces a buffered io.Reader that automatically releases its read buffer when empty. To optimize memory usage, the reader defers buffer reallocation until data is available in the underlying readyreader.Reader (achieved by calling ReadOnReady).

In a follow-up PR (#9032), the HTTP/2 framer will be updated to utilize this new buffered reader whenever the underlying reader implements the readyreader.Reader interface.

The implementation and associated tests are based on the standard library's.

RELEASE NOTES: N/A

@arjan-bal arjan-bal added this to the 1.81 Release milestone Apr 10, 2026
@arjan-bal arjan-bal added Type: Performance Performance improvements (CPU, network, memory, etc) Area: Transport Includes HTTP/2 client/server and HTTP server handler transports and advanced transport features. labels Apr 10, 2026
@arjan-bal

Copy link
Copy Markdown
Contributor Author

/gemini review

@codecov

codecov Bot commented Apr 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 90.90909% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 83.15%. Comparing base (cdc60df) to head (d721aea).
⚠️ Report is 6 commits behind head on master.

Files with missing lines Patch % Lines
internal/transport/readyreader/ready_reader.go 90.90% 2 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #9055      +/-   ##
==========================================
+ Coverage   82.91%   83.15%   +0.23%     
==========================================
  Files         413      413              
  Lines       33404    33430      +26     
==========================================
+ Hits        27698    27799     +101     
+ Misses       4230     4218      -12     
+ Partials     1476     1413      -63     
Files with missing lines Coverage Δ
internal/transport/readyreader/ready_reader.go 83.50% <90.90%> (+31.04%) ⬆️

... and 30 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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

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.

Code Review

This pull request generalizes the readyreader package to accept io.Reader instead of net.Conn and introduces bufReadyReader to provide a buffered io.Reader interface over a ReadyReader. The changes include updated logic for non-blocking reader detection and comprehensive new tests. Review feedback identifies a potential buffer leak in the Read implementation when zero bytes are returned and highlights several documentation inconsistencies and truncated comments that need correction.

Comment thread internal/transport/readyreader/ready_reader.go Outdated
Comment thread internal/transport/readyreader/ready_reader.go Outdated
Comment thread internal/transport/readyreader/ready_reader.go Outdated
Comment thread internal/transport/readyreader/ready_reader.go Outdated
arjan-bal and others added 2 commits April 10, 2026 22:14
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

@easwars easwars left a comment

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.

Changes look mostly good. I still haven't looked at the tests yet.

Comment thread internal/transport/readyreader/ready_reader.go Outdated
Comment thread internal/transport/readyreader/ready_reader.go Outdated
Comment thread internal/transport/readyreader/ready_reader.go Outdated
Comment thread internal/transport/readyreader/ready_reader.go Outdated
Comment thread internal/transport/readyreader/ready_reader.go Outdated
Comment thread internal/transport/readyreader/ready_reader.go Outdated
if b.err != nil {
return 0, b.readErr()
}
if len(p) >= b.bufSize {

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.

Would it nicer to structure this as follows:

if b.r == b.w {
  ...
  var pool mem.BufferPool
  if len(p) >= b.bufSize {
    b.constPool.buffer = p
    pool = &b.constPool
  } else {
    pool = b.pool
  }
  // Rest is common for both paths now

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

If we're reading directly into the caller's buffer, we need to return early to avoid modifying the read/write pointers. Combining these cases would require adding another check further down to handle the early return.

Comment thread internal/transport/readyreader/ready_reader.go
@easwars easwars assigned arjan-bal and unassigned easwars and mbissa Apr 14, 2026
@arjan-bal arjan-bal assigned easwars and unassigned arjan-bal Apr 15, 2026
@easwars

easwars commented Apr 15, 2026

Copy link
Copy Markdown
Contributor

@arjan-bal Did you forget to send your replies to my comments?

@easwars easwars assigned arjan-bal and unassigned easwars Apr 15, 2026
@arjan-bal arjan-bal assigned easwars and unassigned arjan-bal Apr 15, 2026
@easwars easwars removed their assignment Apr 16, 2026
@arjan-bal arjan-bal merged commit bac4588 into grpc:master Apr 16, 2026
21 of 22 checks passed
@arjan-bal arjan-bal modified the milestones: 1.82 Release, 1.81 Release Apr 27, 2026
arjan-bal added a commit that referenced this pull request Apr 27, 2026
Original PRs: #9055, #9032

RELEASE NOTES:
* transport: Pool HTTP/2 framer read buffers to reduce idle memory
consumption. Currently limited to Linux for ALTS and non-encrypted
transports (TCP, Unix). To disable, set
`GRPC_GO_EXPERIMENTAL_HTTP_FRAMER_READ_BUFFER_POOLING=false` and report
any issues.

---------

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: Transport Includes HTTP/2 client/server and HTTP server handler transports and advanced transport features. Type: Performance Performance improvements (CPU, network, memory, etc)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants