-
Notifications
You must be signed in to change notification settings - Fork 4.5k
transport: Re-use slice buffer reader for a stream #8360
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #8360 +/- ##
==========================================
- Coverage 82.35% 82.25% -0.10%
==========================================
Files 419 419
Lines 42034 42052 +18
==========================================
- Hits 34615 34588 -27
- Misses 5968 6001 +33
- Partials 1451 1463 +12
🚀 New features to boost your workflow:
|
ef4e1a9
to
6026288
Compare
mem/buffer_slice.go
Outdated
r.Close() | ||
s.Ref() | ||
r.data = s | ||
r.len = s.Len() | ||
r.bufferIdx = 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could optimize very slightly by not calling r.Close()
and just calling r.data.Free()
instead, since you are initializing every field here.
But...that makes me wonder: why does Close
bother clearing data
and len
in the first place? I am thinking that's done intentionally "in case a read happens after Close
". If so, then are we sure it is okay to re-use them?
cc @PapaCharlie in case he remembers the motivation for this and can comment on the feasibility about reusing the readers here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to avoid redundant work in Reset
. The godoc for Close
mentions that it's okay for readers to call Read
after close.
Subsequent calls to Read will return (0, io.EOF).
If Read
was not allowed after Close
, we could have pooled the Reader
objects, putting object back in the pool at the end of Close
. With the Reset
method, the caller gets to decide when to call Reset
. If they plan to Read
from the old buffer slice later, they should not call Reset
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That makes sense. We might have some places that are reading after Close, but presumably the control buf isn't one of them.
mem/buffer_slice.go
Outdated
r.Close() | ||
s.Ref() | ||
r.data = s | ||
r.len = s.Len() | ||
r.bufferIdx = 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That makes sense. We might have some places that are reading after Close, but presumably the control buf isn't one of them.
This introduces a new method to reset the BufferSlice being used by a
mem.Reader
. The enables using a singleReader
for an HTTP/2 stream instead of allocating one object per gRPC message. This reduces allocs/op, but doesn't have a noticable impact on qps or latency.Benchmarks
RELEASE NOTES: