Skip to content

Commit

Permalink
don't close for i/o errors to match prior behavior
Browse files Browse the repository at this point in the history
  • Loading branch information
dfawley committed Feb 9, 2024
1 parent f416f95 commit ff4b564
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 16 deletions.
12 changes: 7 additions & 5 deletions internal/transport/http2_client.go
Expand Up @@ -451,11 +451,13 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts
}
go func() {
t.loopy = newLoopyWriter(clientSide, t.framer, t.controlBuf, t.bdpEst, t.conn, t.logger)
t.loopy.run()
// Immediately close the connection, as the loopy writer returns when
// there are no more active streams and we were draining (the server
// sent a GOAWAY).
t.conn.Close()
if err := t.loopy.run(); !isIOError(err) {
// Immediately close the connection, as the loopy writer returns
// when there are no more active streams and we were draining (the
// server sent a GOAWAY). For I/O errors, the reader will hit it
// after draining any remaining incoming data.
t.conn.Close()
}
close(t.writerDone)
}()
return t, nil
Expand Down
27 changes: 16 additions & 11 deletions internal/transport/http2_server.go
Expand Up @@ -322,19 +322,24 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport,
go func() {
t.loopy = newLoopyWriter(serverSide, t.framer, t.controlBuf, t.bdpEst, t.conn, t.logger)
t.loopy.ssGoAwayHandler = t.outgoingGoAwayHandler
t.loopy.run()
err := t.loopy.run()
close(t.loopyWriterDone)
// Wait 1 second before closing the connection, or when the reader is
// done (i.e. the client already closed the connection or a connection
// error occurred). This avoids the potential problem where there is
// unread data on the receive side of the connection, which, if closed,
// would lead to a TCP RST instead of FIN, and the client encountering
// errors. For more info: https://github.com/grpc/grpc-go/issues/5358
select {
case <-t.readerDone:
case <-time.After(time.Second):
if !isIOError(err) {
// Close the connection if a non-I/O error occurs (for I/O errors
// the reader will also encounter the error and close). Wait 1
// second before closing the connection, or when the reader is done
// (i.e. the client already closed the connection or a connection
// error occurred). This avoids the potential problem where there
// is unread data on the receive side of the connection, which, if
// closed, would lead to a TCP RST instead of FIN, and the client
// encountering errors. For more info:
// https://github.com/grpc/grpc-go/issues/5358
select {
case <-t.readerDone:
case <-time.After(time.Second):
}
t.conn.Close()
}
t.conn.Close()
}()
go t.keepalive()
return t, nil
Expand Down

0 comments on commit ff4b564

Please sign in to comment.