Skip to content

Commit 61b7262

Browse files
authored
Notify of quiescing when there are no open streams (#1819)
1 parent a6a4539 commit 61b7262

File tree

2 files changed

+10
-3
lines changed

2 files changed

+10
-3
lines changed

Sources/GRPC/GRPCIdleHandlerStateMachine.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -414,12 +414,12 @@ struct GRPCIdleHandlerStateMachine {
414414

415415
switch self.state {
416416
case let .operating(state):
417+
operations.notifyConnectionManager(about: .quiescing)
417418
if state.hasOpenStreams {
418419
// There are open streams: send a GOAWAY frame and wait for the stream count to reach zero.
419420
//
420421
// It's okay if we haven't seen a SETTINGS frame at this point; we've initiated the shutdown
421422
// so making a connection is ready isn't necessary.
422-
operations.notifyConnectionManager(about: .quiescing)
423423

424424
// TODO: we should ratchet down the last initiated stream after 1-RTT.
425425
//
@@ -475,8 +475,8 @@ struct GRPCIdleHandlerStateMachine {
475475
// A SETTINGS frame MUST follow the connection preface. (RFC 7540 § 3.5)
476476
assert(state.hasSeenSettings)
477477

478+
operations.notifyConnectionManager(about: .quiescing)
478479
if state.hasOpenStreams {
479-
operations.notifyConnectionManager(about: .quiescing)
480480
switch state.role {
481481
case .client:
482482
// The server sent us a GOAWAY we'll just stop opening new streams and will send a GOAWAY
@@ -500,7 +500,9 @@ struct GRPCIdleHandlerStateMachine {
500500
case let .waitingToIdle(state):
501501
// There can't be any open streams, but we have a few loose ends to clear up: we need to
502502
// cancel the idle timeout, send a GOAWAY frame and then close.
503+
// We should also notify the connection manager that quiescing is happening.
503504
self.state = .closing(.init(fromWaitingToIdle: state))
505+
operations.notifyConnectionManager(about: .quiescing)
504506
operations.cancelIdleTask(state.idleTask)
505507
operations.sendGoAwayFrame(lastPeerInitiatedStreamID: state.lastPeerInitiatedStreamID)
506508
operations.closeChannel()

Tests/GRPCTests/GRPCIdleHandlerStateMachineTests.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ class GRPCIdleHandlerStateMachineTests: GRPCTestCase {
194194
op3.assertGoAway(streamID: .rootStream)
195195
op3.assertShouldClose()
196196
op3.assertCancelIdleTimeout()
197+
op3.assertConnectionManager(.quiescing)
197198

198199
// Close; we were going to go idle anyway.
199200
let op4 = stateMachine.channelInactive()
@@ -207,6 +208,7 @@ class GRPCIdleHandlerStateMachineTests: GRPCTestCase {
207208
let op1 = stateMachine.initiateGracefulShutdown()
208209
op1.assertGoAway(streamID: .rootStream)
209210
op1.assertShouldClose()
211+
op1.assertConnectionManager(.quiescing)
210212

211213
// Closed.
212214
let op2 = stateMachine.channelInactive()
@@ -223,6 +225,7 @@ class GRPCIdleHandlerStateMachineTests: GRPCTestCase {
223225
// Initiate shutdown.
224226
let op2 = stateMachine.initiateGracefulShutdown()
225227
op2.assertShouldNotClose()
228+
op2.assertConnectionManager(.quiescing)
226229

227230
// Receive a GOAWAY; no change.
228231
let op3 = stateMachine.receiveGoAway()
@@ -467,8 +470,9 @@ class GRPCIdleHandlerStateMachineTests: GRPCTestCase {
467470
let op5 = stateMachine.receiveGoAway()
468471
// We're the client, there are no server initiated streams, so GOAWAY with root stream.
469472
op5.assertGoAway(streamID: 0)
470-
// No open streams, so we can close now.
473+
// No open streams, so we can close now. Also assert the connection manager got a quiescing event.
471474
op5.assertShouldClose()
475+
op5.assertConnectionManager(.quiescing)
472476

473477
// Closed.
474478
let op6 = stateMachine.channelInactive()
@@ -495,6 +499,7 @@ class GRPCIdleHandlerStateMachineTests: GRPCTestCase {
495499
let op4 = stateMachine.receiveGoAway()
496500
op4.assertGoAway(streamID: .maxID)
497501
op4.assertShouldPingAfterGoAway()
502+
op4.assertConnectionManager(.quiescing)
498503

499504
// Create another stream. This is fine, the client hasn't ack'd the ping yet.
500505
let op5 = stateMachine.streamCreated(withID: 7)

0 commit comments

Comments
 (0)