Skip to content
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

[Merged by Bors] - p2p: server: fix incorrect bufio usage #6470

Closed
wants to merge 2 commits into from

Conversation

ivan4th
Copy link
Contributor

@ivan4th ivan4th commented Nov 19, 2024

Motivation

It is not correct to use bufio.Buffer to read the initial request
and then passing the underlying stream to the StreamRequest
callback, as bufio.Buffer may happen to read more data than
necessary, making it unavailable for the StreamRequest callback.
This behavior has been obvserved when using QUIC, which tends to
coalesce multiple writes more often.

Description

This removes unneeded bufio.Buffer usage, which should not impact
performance as the buffer was not being used for the actual request
handling, anyway.

Test Plan

Verified that this fixes QUIC write coalescing issue.

It is not correct to use `bufio.Buffer` to read the initial request
and then passing the underlying stream to the `StreamRequest`
callback, as `bufio.Buffer` may happen to read more data than
necessary, making it unavailable for the `StreamRequest` callback.
This behavior has been obvserved when using QUIC, which tends to
coalesce multiple writes more often.
Comment on lines +172 to +176
func (dadj *deadlineAdjuster) ReadByte() (byte, error) {
var b [1]byte
_, err := io.ReadFull(dadj, b[:])
return b[0], err
}
Copy link
Member

@fasmat fasmat Nov 19, 2024

Choose a reason for hiding this comment

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

Why is io.ReadFull necessary? Doesn't Read guarantee that at least 1 byte is read if err == nil?

Suggested change
func (dadj *deadlineAdjuster) ReadByte() (byte, error) {
var b [1]byte
_, err := io.ReadFull(dadj, b[:])
return b[0], err
}
func (dadj *deadlineAdjuster) ReadByte() (byte, error) {
var b [1]byte
_, err := dadj.Read(b[:])
return b[0], err
}

Copy link
Contributor Author

@ivan4th ivan4th Nov 19, 2024

Choose a reason for hiding this comment

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

According to io.Reader docs:

Implementations of Read are discouraged from returning a zero byte count with a nil error, except when len(p) == 0. Callers should treat a return of 0 and nil as indicating that nothing happened; in particular it does not indicate EOF.

Thus, while it's not good for implementations to return zero byte count with a nil error with len(p) != 0, this possibility cannot be ruled out completely, and the callers are told explicitly to be able to handle such situations; which io.ReadFull does.

Copy link

codecov bot commented Nov 19, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 79.9%. Comparing base (86ac1f4) to head (4211315).
Report is 1 commits behind head on develop.

Additional details and impacted files
@@            Coverage Diff            @@
##           develop   #6470     +/-   ##
=========================================
- Coverage     79.9%   79.9%   -0.1%     
=========================================
  Files          353     353             
  Lines        46432   46435      +3     
=========================================
- Hits         37122   37113      -9     
- Misses        7210    7219      +9     
- Partials      2100    2103      +3     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.


🚨 Try these New Features:

@ivan4th
Copy link
Contributor Author

ivan4th commented Nov 19, 2024

bors merge

spacemesh-bors bot pushed a commit that referenced this pull request Nov 19, 2024
## Motivation

It is not correct to use `bufio.Buffer` to read the initial request
and then passing the underlying stream to the `StreamRequest`
callback, as `bufio.Buffer` may happen to read more data than
necessary, making it unavailable for the `StreamRequest` callback.
This behavior has been obvserved when using QUIC, which tends to
coalesce multiple writes more often.
@spacemesh-bors
Copy link

Pull request successfully merged into develop.

Build succeeded:

@spacemesh-bors spacemesh-bors bot changed the title p2p: server: fix incorrect bufio usage [Merged by Bors] - p2p: server: fix incorrect bufio usage Nov 19, 2024
@spacemesh-bors spacemesh-bors bot closed this Nov 19, 2024
@spacemesh-bors spacemesh-bors bot deleted the fix/p2p-server-buffering branch November 19, 2024 17:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants