Skip to content

Commit 61f63a7

Browse files
authored
Delay closing until the next loop tick (#1326) (#1335)
Motivation: When the idle handler determines that the channel needs to be closed (becuase the connection is no longer required) it does so on the current event loop tick. Closing immediately means that some events which are already scheduled to run on the current tick may be dropped unexpectedly. Modifications: - Execute the channel close on the next event-loop tick. - Fixup a test which now requires an extra loop `run()`. Result: Shutdown is a little more graceful. (cherry picked from commit c43be58)
1 parent a5bc23d commit 61f63a7

File tree

2 files changed

+7
-2
lines changed

2 files changed

+7
-2
lines changed

Sources/GRPC/GRPCIdleHandler.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,12 @@ internal final class GRPCIdleHandler: ChannelInboundHandler {
157157
}
158158

159159
// Close the channel, if necessary.
160-
if operations.shouldCloseChannel {
161-
self.context?.close(mode: .all, promise: nil)
160+
if operations.shouldCloseChannel, let context = self.context {
161+
// Close on the next event-loop tick so we don't drop any events which are
162+
// currently being processed.
163+
context.eventLoop.execute {
164+
context.close(mode: .all, promise: nil)
165+
}
162166
}
163167
}
164168

Tests/GRPCTests/ConnectionManagerTests.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -800,6 +800,7 @@ extension ConnectionManagerTests {
800800
payload: .goAway(lastStreamID: 1, errorCode: .noError, opaqueData: nil)
801801
)
802802
XCTAssertNoThrow(try channel.writeInbound(goAway))
803+
self.loop.run()
803804
}
804805

805806
self.loop.run()

0 commit comments

Comments
 (0)