mirror of
https://github.com/golang/net.git
synced 2026-03-31 18:37:08 +09:00
internal/http3: avoid blocking when closing a server's QUIC endpoint
Several tests such as TestServerReceivePushStream are currently flaky. This is because the synctest test finishes before the test server finishes closing its QUIC endpoint. To prevent this flakiness, make sure that the server uses a canceled context when closing the QUIC endpoint, so as to not block. Fixes golang/go#78100 Fixes golang/go#78101 Fixes golang/go#78102 Change-Id: I88a257d68dfbcf4e1f18b600a2f11dfdabecb078 Reviewed-on: https://go-review.googlesource.com/c/net/+/754740 Reviewed-by: Damien Neil <dneil@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Nicholas Husin <husin@google.com>
This commit is contained in:
committed by
Nicholas Husin
parent
316e20ce34
commit
af2121a04e
@@ -4,7 +4,10 @@
|
||||
|
||||
package http3
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Stream types.
|
||||
//
|
||||
@@ -31,6 +34,14 @@ const (
|
||||
streamTypeDecoder = streamType(0x03)
|
||||
)
|
||||
|
||||
// canceledCtx is a canceled Context.
|
||||
// Used for performing non-blocking QUIC operations.
|
||||
var canceledCtx = func() context.Context {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
cancel()
|
||||
return ctx
|
||||
}()
|
||||
|
||||
func (stype streamType) String() string {
|
||||
switch stype {
|
||||
case streamTypeRequest:
|
||||
|
||||
@@ -128,7 +128,7 @@ func (s *server) listenAndServe(addr string) error {
|
||||
// and handles requests from those connections.
|
||||
func (s *server) serve(e *quic.Endpoint) error {
|
||||
s.init()
|
||||
defer e.Close(s.serveCtx)
|
||||
defer e.Close(canceledCtx)
|
||||
for {
|
||||
qconn, err := e.Accept(s.serveCtx)
|
||||
if err != nil {
|
||||
|
||||
@@ -126,9 +126,7 @@ func (cc *clientConn) close() error {
|
||||
cc.qconn.Abort(nil)
|
||||
|
||||
// Return any existing error from the peer, but don't wait for it.
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
cancel()
|
||||
return cc.qconn.Wait(ctx)
|
||||
return cc.qconn.Wait(canceledCtx)
|
||||
}
|
||||
|
||||
func (cc *clientConn) handleControlStream(st *stream) error {
|
||||
|
||||
@@ -160,9 +160,7 @@ func (ts *testQUICStream) wantIdle(reason string) {
|
||||
ts.t.Helper()
|
||||
synctest.Wait()
|
||||
qs := ts.stream.stream
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
cancel()
|
||||
qs.SetReadContext(ctx)
|
||||
qs.SetReadContext(canceledCtx)
|
||||
if _, err := qs.Read(make([]byte, 1)); !errors.Is(err, context.Canceled) {
|
||||
ts.t.Fatalf("%v: want stream to be idle, but stream has content", reason)
|
||||
}
|
||||
@@ -523,11 +521,3 @@ func (tc *testClientConn) roundTrip(req *http.Request) *testRoundTrip {
|
||||
}()
|
||||
return rt
|
||||
}
|
||||
|
||||
// canceledCtx is a canceled Context.
|
||||
// Used for performing non-blocking QUIC operations.
|
||||
var canceledCtx = func() context.Context {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
cancel()
|
||||
return ctx
|
||||
}()
|
||||
|
||||
Reference in New Issue
Block a user