quic: don't block Writes on stream-level flow control

Data written to a stream can be sent to the peer in a STREAM
frame only when:

- congestion control window is available
- pacing does not block sending
- stream-level flow control is available
- connection-level flow control is available

There must be a pushback mechanism to limit the amount of
locally buffered stream data, but I no longer believe the
stream-level flow control needs to be part of that pushback.

Using connection-level flow control (not yet implemented)
to block stream Write calls is problematic, because it
makes it difficult to fairly divide available send capacity
between multiple streams. If writes to a stream consume
connection-level flow control before we commit that
data to the wire, it becomes very easy for one stream to
starve others.

It's confusing to use stream-level flow control to block
Write calls, but not connection-level flow control.
This will especially produce unexpected behavior
if the recipient chooses to provide unlimited stream-level
quota but limited connection-level quota.

Change Stream.Write to only block writes based on the
configured maximum send buffer size. We may now buffer data
which cannot be immediately sent, but that was the case already
when transmission is blocked by congestion control.

In the future, we may want to make the stream buffer sizes
adaptive in response to the amount of in-flight data.
Rename Config.Stream*BufferSize to MaxStream*BufferSize,
to allow for possibly adding a minimum size later.

For golang/go#58547

Change-Id: I528a611fefb16b323776965c5b2ab5644035ed7a
Reviewed-on: https://go-review.googlesource.com/c/net/+/524958
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Commit-Queue: Damien Neil <dneil@google.com>
Auto-Submit: Damien Neil <dneil@google.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
10 files changed
tree: a778c14e84e564509d0df6cdcc35f0461dc7136d
  1. bpf/
  2. context/
  3. dict/
  4. dns/
  5. html/
  6. http/
  7. http2/
  8. icmp/
  9. idna/
  10. internal/
  11. ipv4/
  12. ipv6/
  13. lif/
  14. nettest/
  15. netutil/
  16. proxy/
  17. publicsuffix/
  18. route/
  19. trace/
  20. webdav/
  21. websocket/
  22. xsrftoken/
  23. .gitattributes
  24. .gitignore
  25. codereview.cfg
  26. CONTRIBUTING.md
  27. go.mod
  28. go.sum
  29. LICENSE
  30. PATENTS
  31. README.md
README.md

Go Networking

Go Reference

This repository holds supplementary Go networking libraries.

Download/Install

The easiest way to install is to run go get -u golang.org/x/net. You can also manually git clone the repository to $GOPATH/src/golang.org/x/net.

Report Issues / Send Patches

This repository uses Gerrit for code changes. To learn how to submit changes to this repository, see https://golang.org/doc/contribute.html. The main issue tracker for the net repository is located at https://github.com/golang/go/issues. Prefix your issue with “x/net:” in the subject line, so it is easy to find.