@@ -46,9 +46,9 @@ var nullMemoryManager = &nullMemoryManagerImpl{}
46
46
type Session struct {
47
47
rtt int64 // to be accessed atomically, in nanoseconds
48
48
49
- // remoteGoAway indicates the remote side does
49
+ // remoteGoAwayNormal indicates the remote side does
50
50
// not want futher connections. Must be first for alignment.
51
- remoteGoAway int32
51
+ remoteGoAwayNormal int32
52
52
53
53
// localGoAway indicates that we should stop
54
54
// accepting futher connections. Must be first for alignment.
@@ -205,8 +205,8 @@ func (s *Session) OpenStream(ctx context.Context) (*Stream, error) {
205
205
if s .IsClosed () {
206
206
return nil , s .shutdownErr
207
207
}
208
- if atomic .LoadInt32 (& s .remoteGoAway ) == 1 {
209
- return nil , ErrRemoteGoAway
208
+ if atomic .LoadInt32 (& s .remoteGoAwayNormal ) == 1 {
209
+ return nil , ErrRemoteGoAwayNormal
210
210
}
211
211
212
212
// Block if we have too many inflight SYNs
@@ -285,15 +285,15 @@ func (s *Session) AcceptStream() (*Stream, error) {
285
285
}
286
286
}
287
287
288
- // Close is used to close the session and all streams.
289
- // Attempts to send a GoAway before closing the connection. The GoAway may not actually be sent depending on the
290
- // semantics of the underlying net.Conn. For TCP connections, it may be dropped depending on LINGER value or
291
- // if there's unread data in the kernel receive buffer.
288
+ // Close is used to close the session and all streams. It doesn't send a GoAway before
289
+ // closing the connection.
292
290
func (s * Session ) Close () error {
293
291
return s .close (ErrSessionShutdown , false , goAwayNormal )
294
292
}
295
293
296
294
// CloseWithError is used to close the session and all streams after sending a GoAway message with errCode.
295
+ // Blocks for ConnectionWriteTimeout to write the GoAway message.
296
+ //
297
297
// The GoAway may not actually be sent depending on the semantics of the underlying net.Conn.
298
298
// For TCP connections, it may be dropped depending on LINGER value or if there's unread data in the kernel
299
299
// receive buffer.
@@ -315,7 +315,8 @@ func (s *Session) close(shutdownErr error, sendGoAway bool, errCode uint32) erro
315
315
close (s .shutdownCh )
316
316
s .stopKeepalive ()
317
317
318
- if sendGoAway {
318
+ // Only send GoAway if we have an error code.
319
+ if sendGoAway && errCode != goAwayNormal {
319
320
// wait for write loop to exit
320
321
// We need to write the current frame completely before sending a goaway.
321
322
// This will wait for at most s.config.ConnectionWriteTimeout
@@ -334,7 +335,7 @@ func (s *Session) close(shutdownErr error, sendGoAway bool, errCode uint32) erro
334
335
s .streamLock .Lock ()
335
336
defer s .streamLock .Unlock ()
336
337
for id , stream := range s .streams {
337
- stream .forceClose (fmt . Errorf ( "%w: connection closed: %w" , ErrStreamReset , s .shutdownErr ) )
338
+ stream .forceClose (s .shutdownErr )
338
339
delete (s .streams , id )
339
340
stream .memorySpan .Done ()
340
341
}
@@ -814,7 +815,7 @@ func (s *Session) handleGoAway(hdr header) error {
814
815
code := hdr .Length ()
815
816
switch code {
816
817
case goAwayNormal :
817
- atomic .SwapInt32 (& s .remoteGoAway , 1 )
818
+ atomic .SwapInt32 (& s .remoteGoAwayNormal , 1 )
818
819
// Don't close connection on normal go away. Let the existing streams
819
820
// complete gracefully.
820
821
return nil
0 commit comments