diff --git a/Package.swift b/Package.swift index b1e8d24..38c854d 100644 --- a/Package.swift +++ b/Package.swift @@ -30,12 +30,12 @@ let package = Package( ], targets: [ .target(name: "NIOTransportServices", - dependencies: ["NIO", "NIOFoundationCompat", "NIOConcurrencyHelpers", "NIOTLS"]), + dependencies: ["NIO", "NIOFoundationCompat", "NIOConcurrencyHelpers", "NIOTLS", "_NIO1APIShims"]), .target(name: "NIOTSHTTPClient", - dependencies: ["NIO", "NIOTransportServices", "NIOHTTP1"]), + dependencies: ["NIO", "NIOTransportServices", "NIOHTTP1", "_NIO1APIShims"]), .target(name: "NIOTSHTTPServer", - dependencies: ["NIO", "NIOTransportServices", "NIOHTTP1"]), + dependencies: ["NIO", "NIOTransportServices", "NIOHTTP1", "_NIO1APIShims"]), .testTarget(name: "NIOTransportServicesTests", - dependencies: ["NIO", "NIOTransportServices"]), + dependencies: ["NIO", "NIOTransportServices", "_NIO1APIShims"]), ] ) diff --git a/Sources/NIOTransportServices/NIOTSConnectionBootstrap.swift b/Sources/NIOTransportServices/NIOTSConnectionBootstrap.swift index 2902f8f..a1f0b21 100644 --- a/Sources/NIOTransportServices/NIOTSConnectionBootstrap.swift +++ b/Sources/NIOTransportServices/NIOTSConnectionBootstrap.swift @@ -150,27 +150,27 @@ public final class NIOTSConnectionBootstrap { let channelOptions = self.channelOptions return conn.eventLoop.submit { - return channelOptions.applyAll(channel: conn).then { + return channelOptions.applyAll(channel: conn).flatMap { initializer(conn) - }.then { - conn.register() - }.then { - let connectPromise: EventLoopPromise = conn.eventLoop.makePromise() - connectAction(conn, connectPromise) - let cancelTask = conn.eventLoop.scheduleTask(in: self.connectTimeout) { - connectPromise.fail(error: ChannelError.connectTimeout(self.connectTimeout)) - conn.close(promise: nil) - } - - connectPromise.futureResult.whenComplete { (_: Result) in - cancelTask.cancel() - } - return connectPromise.futureResult - }.map { conn }.thenIfErrorThrowing { + }.flatMap { + conn.register() + }.flatMap { + let connectPromise: EventLoopPromise = conn.eventLoop.makePromise() + connectAction(conn, connectPromise) + let cancelTask = conn.eventLoop.scheduleTask(in: self.connectTimeout) { + connectPromise.fail(error: ChannelError.connectTimeout(self.connectTimeout)) conn.close(promise: nil) - throw $0 + } + + connectPromise.futureResult.whenComplete { (_: Result) in + cancelTask.cancel() + } + return connectPromise.futureResult + }.map { conn }.flatMapErrorThrowing { + conn.close(promise: nil) + throw $0 } - }.then { $0 } + }.flatMap { $0 } } } diff --git a/Sources/NIOTransportServices/NIOTSEventLoop.swift b/Sources/NIOTransportServices/NIOTSEventLoop.swift index 1b02ad5..f68a4db 100644 --- a/Sources/NIOTransportServices/NIOTSEventLoop.swift +++ b/Sources/NIOTransportServices/NIOTSEventLoop.swift @@ -166,7 +166,7 @@ extension NIOTSEventLoop { // We need to tell all currently-registered channels to close. let futures: [EventLoopFuture] = self.registeredChannels.map { _, channel in channel.close(promise: nil) - return channel.closeFuture.thenIfErrorThrowing { error in + return channel.closeFuture.flatMapErrorThrowing { error in if let error = error as? ChannelError, error == .alreadyClosed { return () } else { diff --git a/Sources/NIOTransportServices/NIOTSListenerBootstrap.swift b/Sources/NIOTransportServices/NIOTSListenerBootstrap.swift index e29e9ea..bbe3c8e 100644 --- a/Sources/NIOTransportServices/NIOTSListenerBootstrap.swift +++ b/Sources/NIOTransportServices/NIOTSListenerBootstrap.swift @@ -16,7 +16,7 @@ import NIO import Dispatch import Network - +import _NIO1APIShims public final class NIOTSListenerBootstrap { private let group: EventLoopGroup @@ -210,26 +210,26 @@ public final class NIOTSListenerBootstrap { tlsOptions: self.tlsOptions) return eventLoop.submit { - return serverChannelOptions.applyAll(channel: serverChannel).then { + return serverChannelOptions.applyAll(channel: serverChannel).flatMap { serverChannelInit(serverChannel) - }.then { + }.flatMap { serverChannel.pipeline.add(handler: AcceptHandler(childChannelInitializer: childChannelInit, childGroup: childEventLoopGroup, childChannelOptions: childChannelOptions, childChannelQoS: self.childQoS, tcpOptions: self.tcpOptions, tlsOptions: self.tlsOptions)) - }.then { + }.flatMap { serverChannel.register() - }.then { + }.flatMap { binder(serverChannel) }.map { serverChannel as Channel - }.thenIfError { error in + }.flatMapError { error in serverChannel.close0(error: error, mode: .all, promise: nil) return eventLoop.makeFailedFuture(error: error) } - }.then { + }.flatMap { $0 } } @@ -275,7 +275,7 @@ private class AcceptHandler: ChannelInboundHandler { @inline(__always) func setupChildChannel() -> EventLoopFuture { - return self.childChannelOptions.applyAll(channel: newChannel).then { () -> EventLoopFuture in + return self.childChannelOptions.applyAll(channel: newChannel).flatMap { () -> EventLoopFuture in childLoop.assertInEventLoop() return childInitializer(newChannel) } @@ -284,10 +284,10 @@ private class AcceptHandler: ChannelInboundHandler { @inline(__always) func fireThroughPipeline(_ future: EventLoopFuture) { ctxEventLoop.assertInEventLoop() - future.then { (_) -> EventLoopFuture in + future.flatMap { (_) -> EventLoopFuture in ctxEventLoop.assertInEventLoop() guard ctx.channel.isActive else { - return newChannel.close().thenThrowing { + return newChannel.close().flatMapThrowing { throw ChannelError.ioOnClosedChannel } } @@ -305,7 +305,7 @@ private class AcceptHandler: ChannelInboundHandler { } else { fireThroughPipeline(childLoop.submit { return setupChildChannel() - }.then { $0 }.hopTo(eventLoop: ctxEventLoop)) + }.flatMap { $0 }.hopTo(eventLoop: ctxEventLoop)) } } } diff --git a/Tests/NIOTransportServicesTests/NIOTSConnectionChannelTests.swift b/Tests/NIOTransportServicesTests/NIOTSConnectionChannelTests.swift index f5aa9ae..a05ebbe 100644 --- a/Tests/NIOTransportServicesTests/NIOTSConnectionChannelTests.swift +++ b/Tests/NIOTransportServicesTests/NIOTSConnectionChannelTests.swift @@ -18,6 +18,7 @@ import Network import NIO import NIOTransportServices import Foundation +import _NIO1APIShims final class ConnectRecordingHandler: ChannelOutboundHandler { @@ -75,7 +76,7 @@ final class DisableWaitingAfterConnect: ChannelOutboundHandler { func connect(ctx: ChannelHandlerContext, to address: SocketAddress, promise: EventLoopPromise?) { - let f = ctx.channel.setOption(option: NIOTSChannelOptions.waitForActivity, value: false).then { + let f = ctx.channel.setOption(option: NIOTSChannelOptions.waitForActivity, value: false).flatMap { ctx.connect(to: address) } if let promise = promise { @@ -255,12 +256,12 @@ class NIOTSConnectionChannelTests: XCTestCase { XCTAssertNoThrow(try connection.close().wait()) } - try connection.getOption(option: ChannelOptions.writeBufferWaterMark).then { option -> EventLoopFuture in + try connection.getOption(option: ChannelOptions.writeBufferWaterMark).flatMap { option -> EventLoopFuture in XCTAssertEqual(option.high, 64 * 1024) XCTAssertEqual(option.low, 32 * 1024) return connection.setOption(option: ChannelOptions.writeBufferWaterMark, value: WriteBufferWaterMark(low: 1, high: 101)) - }.then { + }.flatMap { connection.getOption(option: ChannelOptions.writeBufferWaterMark) }.map { XCTAssertEqual($0.high, 101) @@ -422,31 +423,31 @@ class NIOTSConnectionChannelTests: XCTestCase { XCTAssertTrue(connection.isWritable) }.wait() - try connection.setOption(option: ChannelOptions.writeBufferWaterMark, value: WriteBufferWaterMark(low: 128, high: 256)).then { + try connection.setOption(option: ChannelOptions.writeBufferWaterMark, value: WriteBufferWaterMark(low: 128, high: 256)).flatMap { // High to 256, low to 128. No writability change. XCTAssertEqual(writabilities, []) XCTAssertTrue(connection.isWritable) return connection.setOption(option: ChannelOptions.writeBufferWaterMark, value: WriteBufferWaterMark(low: 128, high: 255)) - }.then { + }.flatMap { // High to 255, low to 127. Channel becomes not writable. XCTAssertEqual(writabilities, [false]) XCTAssertFalse(connection.isWritable) return connection.setOption(option: ChannelOptions.writeBufferWaterMark, value: WriteBufferWaterMark(low: 128, high: 256)) - }.then { + }.flatMap { // High back to 256, low to 128. No writability change. XCTAssertEqual(writabilities, [false]) XCTAssertFalse(connection.isWritable) return connection.setOption(option: ChannelOptions.writeBufferWaterMark, value: WriteBufferWaterMark(low: 256, high: 1024)) - }.then { + }.flatMap { // High to 1024, low to 128. No writability change. XCTAssertEqual(writabilities, [false]) XCTAssertFalse(connection.isWritable) return connection.setOption(option: ChannelOptions.writeBufferWaterMark, value: WriteBufferWaterMark(low: 257, high: 1024)) - }.then { + }.flatMap { // Low to 257, channel becomes writable again. XCTAssertEqual(writabilities, [false, true]) XCTAssertTrue(connection.isWritable) @@ -565,9 +566,9 @@ class NIOTSConnectionChannelTests: XCTestCase { .channelInitializer { channel in return channel.getOption(option: NIOTSChannelOptions.waitForActivity).map { value in XCTAssertTrue(value) - }.then { + }.flatMap { channel.setOption(option: NIOTSChannelOptions.waitForActivity, value: false) - }.then { + }.flatMap { channel.getOption(option: NIOTSChannelOptions.waitForActivity) }.map { value in XCTAssertFalse(value) diff --git a/Tests/NIOTransportServicesTests/NIOTSEndToEndTests.swift b/Tests/NIOTransportServicesTests/NIOTSEndToEndTests.swift index 337c6d7..eb0b5cb 100644 --- a/Tests/NIOTransportServicesTests/NIOTSEndToEndTests.swift +++ b/Tests/NIOTransportServicesTests/NIOTSEndToEndTests.swift @@ -148,7 +148,7 @@ extension Channel { /// Expect that the given bytes will be received. func expectRead(_ bytes: ByteBuffer) -> EventLoopFuture { let expecter = ReadExpecter(expecting: bytes) - return self.pipeline.add(handler: expecter).then { + return self.pipeline.add(handler: expecter).flatMap { return expecter.readFuture! } } @@ -204,7 +204,7 @@ class NIOTSEndToEndTests: XCTestCase { let bootstrap = NIOTSConnectionBootstrap(group: self.group) let completeFutures: [EventLoopFuture] = (0..<10).map { _ in - return bootstrap.connect(to: listener.localAddress!).then { channel -> EventLoopFuture in + return bootstrap.connect(to: listener.localAddress!).flatMap { channel -> EventLoopFuture in let buffer = channel.allocator.bufferFor(string: "hello, world!") let completeFuture = channel.expectRead(buffer) channel.writeAndFlush(buffer, promise: nil) @@ -227,7 +227,7 @@ class NIOTSEndToEndTests: XCTestCase { let bootstrap = NIOTSConnectionBootstrap(group: self.group) let closeFutures: [EventLoopFuture] = (0..<10).map { _ in - bootstrap.connect(to: listener.localAddress!).then { channel in + bootstrap.connect(to: listener.localAddress!).flatMap { channel in channel.closeFuture } } @@ -306,7 +306,7 @@ class NIOTSEndToEndTests: XCTestCase { let halfClosedPromise: EventLoopPromise = self.group.next().makePromise() let listener = try NIOTSListenerBootstrap(group: self.group) .childChannelInitializer { channel in - channel.pipeline.add(handler: EchoHandler()).then { _ in + channel.pipeline.add(handler: EchoHandler()).flatMap { _ in channel.pipeline.add(handler: HalfCloseHandler(halfClosedPromise)) } } @@ -336,7 +336,7 @@ class NIOTSEndToEndTests: XCTestCase { func testDisabledHalfClosureCausesFullClosure() throws { let listener = try NIOTSListenerBootstrap(group: self.group) .childChannelInitializer { channel in - channel.pipeline.add(handler: EchoHandler()).then { _ in + channel.pipeline.add(handler: EchoHandler()).flatMap { _ in channel.pipeline.add(handler: FailOnHalfCloseHandler()) } } diff --git a/Tests/NIOTransportServicesTests/NIOTSSocketOptionsOnChannelTests.swift b/Tests/NIOTransportServicesTests/NIOTSSocketOptionsOnChannelTests.swift index e89eda6..fe09762 100644 --- a/Tests/NIOTransportServicesTests/NIOTSSocketOptionsOnChannelTests.swift +++ b/Tests/NIOTransportServicesTests/NIOTSSocketOptionsOnChannelTests.swift @@ -31,15 +31,15 @@ private extension Channel { /// Asserts that a given socket option has a default value, that its value can be changed to a new value, and that it can then be /// switched back. func assertOptionRoundTrips(option: SocketOption, initialValue: SocketOptionValue, testAlternativeValue: SocketOptionValue) -> EventLoopFuture { - return self.getSocketOption(option).then { actualInitialValue in + return self.getSocketOption(option).flatMap { actualInitialValue in XCTAssertEqual(actualInitialValue, initialValue) return self.setSocketOption(option, to: testAlternativeValue) - }.then { + }.flatMap { self.getSocketOption(option) - }.then { actualNewValue in + }.flatMap { actualNewValue in XCTAssertEqual(actualNewValue, testAlternativeValue) return self.setSocketOption(option, to: initialValue) - }.then { + }.flatMap { self.getSocketOption(option) }.map { returnedToValue in XCTAssertEqual(returnedToValue, initialValue)