Skip to content

Commit

Permalink
Delay closing until the next loop tick (#1326)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
glbrntt authored Dec 14, 2021
1 parent 241bb23 commit c43be58
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 2 deletions.
8 changes: 6 additions & 2 deletions Sources/GRPC/GRPCIdleHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,12 @@ internal final class GRPCIdleHandler: ChannelInboundHandler {
}

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

Expand Down
1 change: 1 addition & 0 deletions Tests/GRPCTests/ConnectionManagerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -800,6 +800,7 @@ extension ConnectionManagerTests {
payload: .goAway(lastStreamID: 1, errorCode: .noError, opaqueData: nil)
)
XCTAssertNoThrow(try channel.writeInbound(goAway))
self.loop.run()
}

self.loop.run()
Expand Down

0 comments on commit c43be58

Please sign in to comment.