add AcceptHandler after serverChannelInitializer runs (#1393)

Motivation:

For compatibility with 2.13.1 and earlier, we're adding the
AcceptHandler after the serverChannelInitializer runs. If that's the
best solution is discussed in #1392.

Modifications:

- add AcceptHandler after the serverChannelInitializer
- give the AcceptHandler the name AcceptHandler

Result:

- better compatibility
This commit is contained in:
Johannes Weiss 2020-02-13 12:55:52 +00:00 committed by GitHub
parent 589bc7cf08
commit 16ab4d657e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 42 additions and 3 deletions

View File

@ -234,10 +234,11 @@ public final class ServerBootstrap {
return eventLoop.submit {
serverChannelOptions.applyAllChannelOptions(to: serverChannel).flatMap {
serverChannel.pipeline.addHandler(AcceptHandler(childChannelInitializer: childChannelInit,
childChannelOptions: childChannelOptions))
}.flatMap {
serverChannelInit(serverChannel)
}.flatMap {
serverChannel.pipeline.addHandler(AcceptHandler(childChannelInitializer: childChannelInit,
childChannelOptions: childChannelOptions),
name: "AcceptHandler")
}.flatMap {
register(eventLoop, serverChannel)
}.map {

View File

@ -39,6 +39,7 @@ extension BootstrapTest {
("testPreConnectedSocketSetsChannelOptionsBeforeChannelInitializer", testPreConnectedSocketSetsChannelOptionsBeforeChannelInitializer),
("testDatagramBootstrapSetsChannelOptionsBeforeChannelInitializer", testDatagramBootstrapSetsChannelOptionsBeforeChannelInitializer),
("testPipeBootstrapSetsChannelOptionsBeforeChannelInitializer", testPipeBootstrapSetsChannelOptionsBeforeChannelInitializer),
("testServerBootstrapAddsAcceptHandlerAfterServerChannelInitialiser", testServerBootstrapAddsAcceptHandlerAfterServerChannelInitialiser),
]
}
}

View File

@ -388,6 +388,43 @@ class BootstrapTest: XCTestCase {
return []
})
}
func testServerBootstrapAddsAcceptHandlerAfterServerChannelInitialiser() {
// It's unclear if this is the right solution, see https://github.com/apple/swift-nio/issues/1392
let group = MultiThreadedEventLoopGroup(numberOfThreads: 1)
defer {
XCTAssertNoThrow(try group.syncShutdownGracefully())
}
struct FoundHandlerThatWasNotSupposedToBeThereError: Error {}
var maybeServer: Channel? = nil
XCTAssertNoThrow(maybeServer = try ServerBootstrap(group: group)
.serverChannelInitializer { channel in
// Here, we test that we can't find the AcceptHandler
return channel.pipeline.context(name: "AcceptHandler").flatMap { context -> EventLoopFuture<Void> in
XCTFail("unexpectedly found \(context)")
return channel.eventLoop.makeFailedFuture(FoundHandlerThatWasNotSupposedToBeThereError())
}.flatMapError { error -> EventLoopFuture<Void> in
XCTAssertEqual(.notFound, error as? ChannelPipelineError)
if case .some(.notFound) = error as? ChannelPipelineError {
return channel.eventLoop.makeSucceededFuture(())
}
return channel.eventLoop.makeFailedFuture(error)
}
}
.bind(host: "127.0.0.1", port: 0)
.wait())
guard let server = maybeServer else {
XCTFail("couldn't bootstrap server")
return
}
// But now, it should be there.
XCTAssertNoThrow(_ = try server.pipeline.context(name: "AcceptHandler").wait())
XCTAssertNoThrow(try server.close().wait())
}
}
private final class MakeSureAutoReadIsOffInChannelInitializer: ChannelInboundHandler {