use to NIO 2 (from master branch) and Swift 5 (#18)
Motivation: SwiftPM from Swift 5.0 brings targets that only support certain systems which is really handy for this package as it only support macOS 10.14+ and iOS/tvOS 12+ Modifications: - made use of the Swift 5.0 manifests which can have restrictions on the supported platforms - adapted to NIO 2 Result: - better development story - using the latest & greatest
This commit is contained in:
parent
ea5ba9bd25
commit
9fa52bd443
|
|
@ -1,4 +1,4 @@
|
||||||
// swift-tools-version:4.0
|
// swift-tools-version:5.0
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
//
|
//
|
||||||
// This source file is part of the SwiftNIO open source project
|
// This source file is part of the SwiftNIO open source project
|
||||||
|
|
@ -17,13 +17,16 @@ import PackageDescription
|
||||||
|
|
||||||
let package = Package(
|
let package = Package(
|
||||||
name: "swift-nio-transport-services",
|
name: "swift-nio-transport-services",
|
||||||
|
platforms: [
|
||||||
|
.macOS(.v10_14), .iOS(.v12), .tvOS(.v12),
|
||||||
|
],
|
||||||
products: [
|
products: [
|
||||||
.library(name: "NIOTransportServices", targets: ["NIOTransportServices"]),
|
.library(name: "NIOTransportServices", targets: ["NIOTransportServices"]),
|
||||||
.executable(name: "NIOTSHTTPClient", targets: ["NIOTSHTTPClient"]),
|
.executable(name: "NIOTSHTTPClient", targets: ["NIOTSHTTPClient"]),
|
||||||
.executable(name: "NIOTSHTTPServer", targets: ["NIOTSHTTPServer"]),
|
.executable(name: "NIOTSHTTPServer", targets: ["NIOTSHTTPServer"]),
|
||||||
],
|
],
|
||||||
dependencies: [
|
dependencies: [
|
||||||
.package(url: "https://github.com/apple/swift-nio.git", from: "1.11.0"),
|
.package(url: "https://github.com/apple/swift-nio.git", .branch("master")),
|
||||||
],
|
],
|
||||||
targets: [
|
targets: [
|
||||||
.target(name: "NIOTransportServices",
|
.target(name: "NIOTransportServices",
|
||||||
|
|
|
||||||
13
README.md
13
README.md
|
|
@ -16,24 +16,21 @@ Network.framework is Apple's reference implementation of the [proposed post-sock
|
||||||
|
|
||||||
## How to Use?
|
## How to Use?
|
||||||
|
|
||||||
Today, the easiest way to use SwiftNIO Transport Services is through CocoaPods:
|
Today, the easiest way to use SwiftNIO Transport Services in an iOS project is through CocoaPods:
|
||||||
|
|
||||||
pod 'SwiftNIO'
|
pod 'SwiftNIO'
|
||||||
pod 'SwiftNIOTransportServices'
|
pod 'SwiftNIOTransportServices'
|
||||||
|
|
||||||
You can also use the Swift Package Manager, however Network.framework is only available on macOS 10.14+, iOS 12+, and tvOS 12+. This does not match the current minimum deployment target for Swift Package Manager, so building this repository with Swift Package Manager requires that you pass custom build flags, e.g:
|
You can also use the Swift Package Manager:
|
||||||
|
|
||||||
```
|
```
|
||||||
swift build -Xswiftc -target -Xswiftc x86_64-apple-macosx10.14
|
swift build
|
||||||
```
|
```
|
||||||
|
|
||||||
Alternatively, if you want to use Xcode to build this repository, you can use the following xcconfig:
|
and add the project as a sub-project by dragging it into your iOS project and adding the frameworks (such as `NIO.framework`) in 'Build Phases' -> 'Link Binary Libraries'.
|
||||||
|
|
||||||
```
|
Do note however that Network.framework requires macOS 10.14+, iOS 12+, or tvOS 12+.
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.14
|
|
||||||
```
|
|
||||||
|
|
||||||
For support in iOS or tvOS, change the targets as necessary.
|
|
||||||
|
|
||||||
## Versioning
|
## Versioning
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,7 @@ public final class NIOTSConnectionBootstrap {
|
||||||
/// - returns: An `EventLoopFuture<Channel>` to deliver the `Channel` when connected.
|
/// - returns: An `EventLoopFuture<Channel>` to deliver the `Channel` when connected.
|
||||||
public func connect(host: String, port: Int) -> EventLoopFuture<Channel> {
|
public func connect(host: String, port: Int) -> EventLoopFuture<Channel> {
|
||||||
guard let actualPort = NWEndpoint.Port(rawValue: UInt16(port)) else {
|
guard let actualPort = NWEndpoint.Port(rawValue: UInt16(port)) else {
|
||||||
return self.group.next().newFailedFuture(error: NIOTSErrors.InvalidPort(port: port))
|
return self.group.next().makeFailedFuture(error: NIOTSErrors.InvalidPort(port: port))
|
||||||
}
|
}
|
||||||
return self.connect(endpoint: NWEndpoint.hostPort(host: .init(host), port: actualPort))
|
return self.connect(endpoint: NWEndpoint.hostPort(host: .init(host), port: actualPort))
|
||||||
}
|
}
|
||||||
|
|
@ -129,7 +129,7 @@ public final class NIOTSConnectionBootstrap {
|
||||||
let address = try SocketAddress(unixDomainSocketPath: unixDomainSocketPath)
|
let address = try SocketAddress(unixDomainSocketPath: unixDomainSocketPath)
|
||||||
return connect(to: address)
|
return connect(to: address)
|
||||||
} catch {
|
} catch {
|
||||||
return group.next().newFailedFuture(error: error)
|
return group.next().makeFailedFuture(error: error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -146,7 +146,7 @@ public final class NIOTSConnectionBootstrap {
|
||||||
qos: self.qos,
|
qos: self.qos,
|
||||||
tcpOptions: self.tcpOptions,
|
tcpOptions: self.tcpOptions,
|
||||||
tlsOptions: self.tlsOptions)
|
tlsOptions: self.tlsOptions)
|
||||||
let initializer = self.channelInitializer ?? { _ in conn.eventLoop.newSucceededFuture(result: ()) }
|
let initializer = self.channelInitializer ?? { _ in conn.eventLoop.makeSucceededFuture(result: ()) }
|
||||||
let channelOptions = self.channelOptions
|
let channelOptions = self.channelOptions
|
||||||
|
|
||||||
return conn.eventLoop.submit {
|
return conn.eventLoop.submit {
|
||||||
|
|
@ -155,14 +155,14 @@ public final class NIOTSConnectionBootstrap {
|
||||||
}.then {
|
}.then {
|
||||||
conn.register()
|
conn.register()
|
||||||
}.then {
|
}.then {
|
||||||
let connectPromise: EventLoopPromise<Void> = conn.eventLoop.newPromise()
|
let connectPromise: EventLoopPromise<Void> = conn.eventLoop.makePromise()
|
||||||
connectAction(conn, connectPromise)
|
connectAction(conn, connectPromise)
|
||||||
let cancelTask = conn.eventLoop.scheduleTask(in: self.connectTimeout) {
|
let cancelTask = conn.eventLoop.scheduleTask(in: self.connectTimeout) {
|
||||||
connectPromise.fail(error: ChannelError.connectTimeout(self.connectTimeout))
|
connectPromise.fail(error: ChannelError.connectTimeout(self.connectTimeout))
|
||||||
conn.close(promise: nil)
|
conn.close(promise: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
connectPromise.futureResult.whenComplete {
|
connectPromise.futureResult.whenComplete { (_: Result<Void, Error>) in
|
||||||
cancelTask.cancel()
|
cancelTask.cancel()
|
||||||
}
|
}
|
||||||
return connectPromise.futureResult
|
return connectPromise.futureResult
|
||||||
|
|
@ -200,7 +200,7 @@ internal struct ChannelOptionStorage {
|
||||||
}
|
}
|
||||||
|
|
||||||
func applyAll(channel: Channel) -> EventLoopFuture<Void> {
|
func applyAll(channel: Channel) -> EventLoopFuture<Void> {
|
||||||
let applyPromise: EventLoopPromise<Void> = channel.eventLoop.newPromise()
|
let applyPromise: EventLoopPromise<Void> = channel.eventLoop.makePromise()
|
||||||
var it = self.storage.makeIterator()
|
var it = self.storage.makeIterator()
|
||||||
|
|
||||||
func applyNext() {
|
func applyNext() {
|
||||||
|
|
|
||||||
|
|
@ -210,7 +210,7 @@ internal final class NIOTSConnectionChannel {
|
||||||
tcpOptions: NWProtocolTCP.Options,
|
tcpOptions: NWProtocolTCP.Options,
|
||||||
tlsOptions: NWProtocolTLS.Options?) {
|
tlsOptions: NWProtocolTLS.Options?) {
|
||||||
self.tsEventLoop = eventLoop
|
self.tsEventLoop = eventLoop
|
||||||
self.closePromise = eventLoop.newPromise()
|
self.closePromise = eventLoop.makePromise()
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
self.connectionQueue = eventLoop.channelQueue(label: "nio.nioTransportServices.connectionchannel", qos: qos)
|
self.connectionQueue = eventLoop.channelQueue(label: "nio.nioTransportServices.connectionchannel", qos: qos)
|
||||||
self.tcpOptions = tcpOptions
|
self.tcpOptions = tcpOptions
|
||||||
|
|
@ -273,7 +273,7 @@ extension NIOTSConnectionChannel: Channel {
|
||||||
|
|
||||||
public func setOption<T>(option: T, value: T.OptionType) -> EventLoopFuture<Void> where T : ChannelOption {
|
public func setOption<T>(option: T, value: T.OptionType) -> EventLoopFuture<Void> where T : ChannelOption {
|
||||||
if eventLoop.inEventLoop {
|
if eventLoop.inEventLoop {
|
||||||
let promise: EventLoopPromise<Void> = eventLoop.newPromise()
|
let promise: EventLoopPromise<Void> = eventLoop.makePromise()
|
||||||
executeAndComplete(promise) { try setOption0(option: option, value: value) }
|
executeAndComplete(promise) { try setOption0(option: option, value: value) }
|
||||||
return promise.futureResult
|
return promise.futureResult
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -325,7 +325,7 @@ extension NIOTSConnectionChannel: Channel {
|
||||||
|
|
||||||
public func getOption<T>(option: T) -> EventLoopFuture<T.OptionType> where T : ChannelOption {
|
public func getOption<T>(option: T) -> EventLoopFuture<T.OptionType> where T : ChannelOption {
|
||||||
if eventLoop.inEventLoop {
|
if eventLoop.inEventLoop {
|
||||||
let promise: EventLoopPromise<T.OptionType> = eventLoop.newPromise()
|
let promise: EventLoopPromise<T.OptionType> = eventLoop.makePromise()
|
||||||
executeAndComplete(promise) { try getOption0(option: option) }
|
executeAndComplete(promise) { try getOption0(option: option) }
|
||||||
return promise.futureResult
|
return promise.futureResult
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,7 @@ internal class NIOTSEventLoop: QoSEventLoop {
|
||||||
}
|
}
|
||||||
|
|
||||||
public func scheduleTask<T>(in time: TimeAmount, qos: DispatchQoS, _ task: @escaping () throws -> T) -> Scheduled<T> {
|
public func scheduleTask<T>(in time: TimeAmount, qos: DispatchQoS, _ task: @escaping () throws -> T) -> Scheduled<T> {
|
||||||
let p: EventLoopPromise<T> = self.newPromise()
|
let p: EventLoopPromise<T> = self.makePromise()
|
||||||
|
|
||||||
guard self.state != .closed else {
|
guard self.state != .closed else {
|
||||||
p.fail(error: EventLoopError.shutdown)
|
p.fail(error: EventLoopError.shutdown)
|
||||||
|
|
@ -153,7 +153,7 @@ extension NIOTSEventLoop {
|
||||||
|
|
||||||
extension NIOTSEventLoop {
|
extension NIOTSEventLoop {
|
||||||
internal func closeGently() -> EventLoopFuture<Void> {
|
internal func closeGently() -> EventLoopFuture<Void> {
|
||||||
let p: EventLoopPromise<Void> = self.newPromise()
|
let p: EventLoopPromise<Void> = self.makePromise()
|
||||||
self.taskQueue.async {
|
self.taskQueue.async {
|
||||||
guard self.open else {
|
guard self.open else {
|
||||||
p.fail(error: EventLoopError.shutdown)
|
p.fail(error: EventLoopError.shutdown)
|
||||||
|
|
@ -181,7 +181,7 @@ extension NIOTSEventLoop {
|
||||||
// event loop it will be forbidden from doing so.
|
// event loop it will be forbidden from doing so.
|
||||||
let completionFuture = EventLoopFuture<Void>.andAll(futures, eventLoop: self)
|
let completionFuture = EventLoopFuture<Void>.andAll(futures, eventLoop: self)
|
||||||
completionFuture.cascade(promise: p)
|
completionFuture.cascade(promise: p)
|
||||||
completionFuture.whenComplete {
|
completionFuture.whenComplete { (_: Result<Void, Error>) in
|
||||||
self.state = .closed
|
self.state = .closed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ public final class NIOTSEventLoopGroup: EventLoopGroup {
|
||||||
g.enter()
|
g.enter()
|
||||||
loop.closeGently().mapIfError { err in
|
loop.closeGently().mapIfError { err in
|
||||||
q.sync { error = err }
|
q.sync { error = err }
|
||||||
}.whenComplete {
|
}.whenComplete { (_: Result<Void, Error>) in
|
||||||
g.leave()
|
g.leave()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -77,4 +77,8 @@ public final class NIOTSEventLoopGroup: EventLoopGroup {
|
||||||
callback(error)
|
callback(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func makeIterator() -> EventLoopIterator {
|
||||||
|
return EventLoopIterator(self.eventLoops)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -145,12 +145,12 @@ public final class NIOTSListenerBootstrap {
|
||||||
/// - port: The port to bind on.
|
/// - port: The port to bind on.
|
||||||
public func bind(host: String, port: Int) -> EventLoopFuture<Channel> {
|
public func bind(host: String, port: Int) -> EventLoopFuture<Channel> {
|
||||||
return self.bind0 { channel in
|
return self.bind0 { channel in
|
||||||
let p: EventLoopPromise<Void> = channel.eventLoop.newPromise()
|
let p: EventLoopPromise<Void> = channel.eventLoop.makePromise()
|
||||||
do {
|
do {
|
||||||
// NWListener does not actually resolve hostname-based NWEndpoints
|
// NWListener does not actually resolve hostname-based NWEndpoints
|
||||||
// for use with requiredLocalEndpoint, so we fall back to
|
// for use with requiredLocalEndpoint, so we fall back to
|
||||||
// SocketAddress for this.
|
// SocketAddress for this.
|
||||||
let address = try SocketAddress.newAddressResolving(host: host, port: port)
|
let address = try SocketAddress.makeAddressResolvingHost(host, port: port)
|
||||||
channel.bind(to: address, promise: p)
|
channel.bind(to: address, promise: p)
|
||||||
} catch {
|
} catch {
|
||||||
p.fail(error: error)
|
p.fail(error: error)
|
||||||
|
|
@ -175,7 +175,7 @@ public final class NIOTSListenerBootstrap {
|
||||||
/// - unixDomainSocketPath: The _Unix domain socket_ path to bind to. `unixDomainSocketPath` must not exist, it will be created by the system.
|
/// - unixDomainSocketPath: The _Unix domain socket_ path to bind to. `unixDomainSocketPath` must not exist, it will be created by the system.
|
||||||
public func bind(unixDomainSocketPath: String) -> EventLoopFuture<Channel> {
|
public func bind(unixDomainSocketPath: String) -> EventLoopFuture<Channel> {
|
||||||
return self.bind0 { channel in
|
return self.bind0 { channel in
|
||||||
let p: EventLoopPromise<Void> = channel.eventLoop.newPromise()
|
let p: EventLoopPromise<Void> = channel.eventLoop.makePromise()
|
||||||
do {
|
do {
|
||||||
let address = try SocketAddress(unixDomainSocketPath: unixDomainSocketPath)
|
let address = try SocketAddress(unixDomainSocketPath: unixDomainSocketPath)
|
||||||
channel.bind(to: address, promise: p)
|
channel.bind(to: address, promise: p)
|
||||||
|
|
@ -199,7 +199,7 @@ public final class NIOTSListenerBootstrap {
|
||||||
private func bind0(_ binder: @escaping (Channel) -> EventLoopFuture<Void>) -> EventLoopFuture<Channel> {
|
private func bind0(_ binder: @escaping (Channel) -> EventLoopFuture<Void>) -> EventLoopFuture<Channel> {
|
||||||
let eventLoop = self.group.next() as! NIOTSEventLoop
|
let eventLoop = self.group.next() as! NIOTSEventLoop
|
||||||
let childEventLoopGroup = self.childGroup as! NIOTSEventLoopGroup
|
let childEventLoopGroup = self.childGroup as! NIOTSEventLoopGroup
|
||||||
let serverChannelInit = self.serverChannelInit ?? { _ in eventLoop.newSucceededFuture(result: ()) }
|
let serverChannelInit = self.serverChannelInit ?? { _ in eventLoop.makeSucceededFuture(result: ()) }
|
||||||
let childChannelInit = self.childChannelInit
|
let childChannelInit = self.childChannelInit
|
||||||
let serverChannelOptions = self.serverChannelOptions
|
let serverChannelOptions = self.serverChannelOptions
|
||||||
let childChannelOptions = self.childChannelOptions
|
let childChannelOptions = self.childChannelOptions
|
||||||
|
|
@ -227,7 +227,7 @@ public final class NIOTSListenerBootstrap {
|
||||||
serverChannel as Channel
|
serverChannel as Channel
|
||||||
}.thenIfError { error in
|
}.thenIfError { error in
|
||||||
serverChannel.close0(error: error, mode: .all, promise: nil)
|
serverChannel.close0(error: error, mode: .all, promise: nil)
|
||||||
return eventLoop.newFailedFuture(error: error)
|
return eventLoop.makeFailedFuture(error: error)
|
||||||
}
|
}
|
||||||
}.then {
|
}.then {
|
||||||
$0
|
$0
|
||||||
|
|
@ -265,7 +265,7 @@ private class AcceptHandler: ChannelInboundHandler {
|
||||||
let conn = self.unwrapInboundIn(data)
|
let conn = self.unwrapInboundIn(data)
|
||||||
let childLoop = self.childGroup.next() as! NIOTSEventLoop
|
let childLoop = self.childGroup.next() as! NIOTSEventLoop
|
||||||
let ctxEventLoop = ctx.eventLoop
|
let ctxEventLoop = ctx.eventLoop
|
||||||
let childInitializer = self.childChannelInitializer ?? { _ in childLoop.newSucceededFuture(result: ()) }
|
let childInitializer = self.childChannelInitializer ?? { _ in childLoop.makeSucceededFuture(result: ()) }
|
||||||
let newChannel = NIOTSConnectionChannel(wrapping: conn,
|
let newChannel = NIOTSConnectionChannel(wrapping: conn,
|
||||||
on: childLoop,
|
on: childLoop,
|
||||||
parent: ctx.channel,
|
parent: ctx.channel,
|
||||||
|
|
@ -292,7 +292,7 @@ private class AcceptHandler: ChannelInboundHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ctx.fireChannelRead(self.wrapInboundOut(newChannel))
|
ctx.fireChannelRead(self.wrapInboundOut(newChannel))
|
||||||
return ctx.eventLoop.newSucceededFuture(result: ())
|
return ctx.eventLoop.makeSucceededFuture(result: ())
|
||||||
}.whenFailure { error in
|
}.whenFailure { error in
|
||||||
ctx.eventLoop.assertInEventLoop()
|
ctx.eventLoop.assertInEventLoop()
|
||||||
_ = newChannel.close()
|
_ = newChannel.close()
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ internal final class NIOTSListenerChannel {
|
||||||
tcpOptions: NWProtocolTCP.Options,
|
tcpOptions: NWProtocolTCP.Options,
|
||||||
tlsOptions: NWProtocolTLS.Options?) {
|
tlsOptions: NWProtocolTLS.Options?) {
|
||||||
self.tsEventLoop = eventLoop
|
self.tsEventLoop = eventLoop
|
||||||
self.closePromise = eventLoop.newPromise()
|
self.closePromise = eventLoop.makePromise()
|
||||||
self.connectionQueue = eventLoop.channelQueue(label: "nio.transportservices.listenerchannel", qos: qos)
|
self.connectionQueue = eventLoop.channelQueue(label: "nio.transportservices.listenerchannel", qos: qos)
|
||||||
self.tcpOptions = tcpOptions
|
self.tcpOptions = tcpOptions
|
||||||
self.tlsOptions = tlsOptions
|
self.tlsOptions = tlsOptions
|
||||||
|
|
@ -134,7 +134,7 @@ extension NIOTSListenerChannel: Channel {
|
||||||
|
|
||||||
public func setOption<T>(option: T, value: T.OptionType) -> EventLoopFuture<Void> where T : ChannelOption {
|
public func setOption<T>(option: T, value: T.OptionType) -> EventLoopFuture<Void> where T : ChannelOption {
|
||||||
if eventLoop.inEventLoop {
|
if eventLoop.inEventLoop {
|
||||||
let promise: EventLoopPromise<Void> = eventLoop.newPromise()
|
let promise: EventLoopPromise<Void> = eventLoop.makePromise()
|
||||||
executeAndComplete(promise) { try setOption0(option: option, value: value) }
|
executeAndComplete(promise) { try setOption0(option: option, value: value) }
|
||||||
return promise.futureResult
|
return promise.futureResult
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -173,7 +173,7 @@ extension NIOTSListenerChannel: Channel {
|
||||||
|
|
||||||
public func getOption<T>(option: T) -> EventLoopFuture<T.OptionType> where T : ChannelOption {
|
public func getOption<T>(option: T) -> EventLoopFuture<T.OptionType> where T : ChannelOption {
|
||||||
if eventLoop.inEventLoop {
|
if eventLoop.inEventLoop {
|
||||||
let promise: EventLoopPromise<T.OptionType> = eventLoop.newPromise()
|
let promise: EventLoopPromise<T.OptionType> = eventLoop.makePromise()
|
||||||
executeAndComplete(promise) { try getOption0(option: option) }
|
executeAndComplete(promise) { try getOption0(option: option) }
|
||||||
return promise.futureResult
|
return promise.futureResult
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -269,6 +269,8 @@ extension NIOTSListenerChannel: StateManagedChannel {
|
||||||
parameters.requiredLocalEndpoint = target
|
parameters.requiredLocalEndpoint = target
|
||||||
case .service(_, _, _, let interface):
|
case .service(_, _, _, let interface):
|
||||||
parameters.requiredInterface = interface
|
parameters.requiredInterface = interface
|
||||||
|
@unknown default:
|
||||||
|
()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Network.framework munges REUSEADDR and REUSEPORT together, so we turn this on if we need
|
// Network.framework munges REUSEADDR and REUSEPORT together, so we turn this on if we need
|
||||||
|
|
@ -342,7 +344,7 @@ extension NIOTSListenerChannel: StateManagedChannel {
|
||||||
self.eventLoop.assertInEventLoop()
|
self.eventLoop.assertInEventLoop()
|
||||||
|
|
||||||
let channel = self.unwrapData(data, as: NIOTSConnectionChannel.self)
|
let channel = self.unwrapData(data, as: NIOTSConnectionChannel.self)
|
||||||
let p: EventLoopPromise<Void> = channel.eventLoop.newPromise()
|
let p: EventLoopPromise<Void> = channel.eventLoop.makePromise()
|
||||||
channel.eventLoop.execute {
|
channel.eventLoop.execute {
|
||||||
channel.registerAlreadyConfigured0(promise: p)
|
channel.registerAlreadyConfigured0(promise: p)
|
||||||
p.futureResult.whenFailure { (_: Error) in
|
p.futureResult.whenFailure { (_: Error) in
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ import Foundation
|
||||||
import NIO
|
import NIO
|
||||||
import Network
|
import Network
|
||||||
|
|
||||||
internal extension IPv4Address {
|
extension IPv4Address {
|
||||||
/// Create an `IPv4Address` object from a `sockaddr_in`.
|
/// Create an `IPv4Address` object from a `sockaddr_in`.
|
||||||
internal init(fromSockAddr sockAddr: sockaddr_in) {
|
internal init(fromSockAddr sockAddr: sockaddr_in) {
|
||||||
var localAddr = sockAddr
|
var localAddr = sockAddr
|
||||||
|
|
@ -30,7 +30,7 @@ internal extension IPv4Address {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal extension IPv6Address {
|
extension IPv6Address {
|
||||||
internal init(fromSockAddr sockAddr: sockaddr_in6) {
|
internal init(fromSockAddr sockAddr: sockaddr_in6) {
|
||||||
var localAddr = sockAddr
|
var localAddr = sockAddr
|
||||||
|
|
||||||
|
|
@ -44,7 +44,7 @@ internal extension IPv6Address {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal extension NWEndpoint {
|
extension NWEndpoint {
|
||||||
/// Create an `NWEndpoint` value from a NIO `SocketAddress`.
|
/// Create an `NWEndpoint` value from a NIO `SocketAddress`.
|
||||||
internal init(fromSocketAddress socketAddress: SocketAddress) {
|
internal init(fromSocketAddress socketAddress: SocketAddress) {
|
||||||
switch socketAddress {
|
switch socketAddress {
|
||||||
|
|
@ -57,11 +57,11 @@ internal extension NWEndpoint {
|
||||||
self = NWEndpoint.unix(path: path)
|
self = NWEndpoint.unix(path: path)
|
||||||
case .v4(let v4Addr):
|
case .v4(let v4Addr):
|
||||||
let v4Address = IPv4Address(fromSockAddr: v4Addr.address)
|
let v4Address = IPv4Address(fromSockAddr: v4Addr.address)
|
||||||
let port = NWEndpoint.Port(rawValue: socketAddress.port!)!
|
let port = NWEndpoint.Port(rawValue: UInt16(socketAddress.port!))!
|
||||||
self = NWEndpoint.hostPort(host: .ipv4(v4Address), port: port)
|
self = NWEndpoint.hostPort(host: .ipv4(v4Address), port: port)
|
||||||
case .v6(let v6Addr):
|
case .v6(let v6Addr):
|
||||||
let v6Address = IPv6Address(fromSockAddr: v6Addr.address)
|
let v6Address = IPv6Address(fromSockAddr: v6Addr.address)
|
||||||
let port = NWEndpoint.Port(rawValue: socketAddress.port!)!
|
let port = NWEndpoint.Port(rawValue: UInt16(socketAddress.port!))!
|
||||||
self = NWEndpoint.hostPort(host: .ipv6(v6Address), port: port)
|
self = NWEndpoint.hostPort(host: .ipv6(v6Address), port: port)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -69,7 +69,7 @@ internal extension NWEndpoint {
|
||||||
|
|
||||||
// TODO: We'll want to get rid of this when we support returning NWEndpoint directly from
|
// TODO: We'll want to get rid of this when we support returning NWEndpoint directly from
|
||||||
// the various address-handling functions.
|
// the various address-handling functions.
|
||||||
internal extension SocketAddress {
|
extension SocketAddress {
|
||||||
internal init(fromNWEndpoint endpoint: NWEndpoint) throws {
|
internal init(fromNWEndpoint endpoint: NWEndpoint) throws {
|
||||||
switch endpoint {
|
switch endpoint {
|
||||||
case .hostPort(.ipv4(let host), let port):
|
case .hostPort(.ipv4(let host), let port):
|
||||||
|
|
@ -96,8 +96,10 @@ internal extension SocketAddress {
|
||||||
self = try .init(unixDomainSocketPath: path)
|
self = try .init(unixDomainSocketPath: path)
|
||||||
case .service:
|
case .service:
|
||||||
preconditionFailure("Cannot represent service addresses in SocketAddress")
|
preconditionFailure("Cannot represent service addresses in SocketAddress")
|
||||||
case .hostPort(.name, _):
|
case .hostPort(_, _):
|
||||||
preconditionFailure("Cannot represent host by name only as SocketAddress")
|
preconditionFailure("Cannot represent unknown host in SocketAddress")
|
||||||
|
@unknown default:
|
||||||
|
preconditionFailure("cannot create SocketAddress from unknown representation")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -74,8 +74,13 @@ final class DisableWaitingAfterConnect: ChannelOutboundHandler {
|
||||||
typealias OutboundOut = Any
|
typealias OutboundOut = Any
|
||||||
|
|
||||||
func connect(ctx: ChannelHandlerContext, to address: SocketAddress, promise: EventLoopPromise<Void>?) {
|
func connect(ctx: ChannelHandlerContext, to address: SocketAddress, promise: EventLoopPromise<Void>?) {
|
||||||
ctx.connect(to: address, promise: promise)
|
|
||||||
ctx.channel.setOption(option: NIOTSChannelOptions.waitForActivity, value: false)
|
let f = ctx.channel.setOption(option: NIOTSChannelOptions.waitForActivity, value: false).then {
|
||||||
|
ctx.connect(to: address)
|
||||||
|
}
|
||||||
|
if let promise = promise {
|
||||||
|
f.cascade(promise: promise)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -151,7 +156,7 @@ class NIOTSConnectionChannelTests: XCTestCase {
|
||||||
|
|
||||||
try connection.eventLoop.submit {
|
try connection.eventLoop.submit {
|
||||||
XCTAssertEqual(connectRecordingHandler.connectTargets, [])
|
XCTAssertEqual(connectRecordingHandler.connectTargets, [])
|
||||||
XCTAssertEqual(connectRecordingHandler.endpointTargets, [NWEndpoint.hostPort(host: "localhost", port: NWEndpoint.Port(rawValue: listener.localAddress!.port!)!)])
|
XCTAssertEqual(connectRecordingHandler.endpointTargets, [NWEndpoint.hostPort(host: "localhost", port: NWEndpoint.Port(rawValue: UInt16(listener.localAddress!.port!))!)])
|
||||||
}.wait()
|
}.wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -168,7 +173,7 @@ class NIOTSConnectionChannelTests: XCTestCase {
|
||||||
XCTAssertEqual(connectRecordingHandler.connectTargets, [])
|
XCTAssertEqual(connectRecordingHandler.connectTargets, [])
|
||||||
XCTAssertEqual(connectRecordingHandler.endpointTargets, [])
|
XCTAssertEqual(connectRecordingHandler.endpointTargets, [])
|
||||||
|
|
||||||
let target = NWEndpoint.hostPort(host: "localhost", port: NWEndpoint.Port(rawValue: listener.localAddress!.port!)!)
|
let target = NWEndpoint.hostPort(host: "localhost", port: NWEndpoint.Port(rawValue: UInt16(listener.localAddress!.port!))!)
|
||||||
|
|
||||||
let connection = try connectBootstrap.connect(endpoint: target).wait()
|
let connection = try connectBootstrap.connect(endpoint: target).wait()
|
||||||
defer {
|
defer {
|
||||||
|
|
@ -306,7 +311,7 @@ class NIOTSConnectionChannelTests: XCTestCase {
|
||||||
|
|
||||||
// Write a. After this write, we are still writable. When this write
|
// Write a. After this write, we are still writable. When this write
|
||||||
// succeeds, we'll still be not writable.
|
// succeeds, we'll still be not writable.
|
||||||
connection.write(buffer.getSlice(at: 0, length: 1)).whenComplete {
|
connection.write(buffer.getSlice(at: 0, length: 1)).whenComplete { (_: Result<Void, Error>) in
|
||||||
XCTAssertEqual(writabilities, [false])
|
XCTAssertEqual(writabilities, [false])
|
||||||
XCTAssertFalse(connection.isWritable)
|
XCTAssertFalse(connection.isWritable)
|
||||||
}
|
}
|
||||||
|
|
@ -315,7 +320,7 @@ class NIOTSConnectionChannelTests: XCTestCase {
|
||||||
|
|
||||||
// Write b. After this write we are still writable. When this write
|
// Write b. After this write we are still writable. When this write
|
||||||
// succeeds we'll still be not writable.
|
// succeeds we'll still be not writable.
|
||||||
connection.write(buffer.getSlice(at: 0, length: 1)).whenComplete {
|
connection.write(buffer.getSlice(at: 0, length: 1)).whenComplete { (_: Result<Void, Error>) in
|
||||||
XCTAssertEqual(writabilities, [false])
|
XCTAssertEqual(writabilities, [false])
|
||||||
XCTAssertFalse(connection.isWritable)
|
XCTAssertFalse(connection.isWritable)
|
||||||
}
|
}
|
||||||
|
|
@ -324,7 +329,7 @@ class NIOTSConnectionChannelTests: XCTestCase {
|
||||||
|
|
||||||
// Write c. After this write we are still writable (2047 bytes written).
|
// Write c. After this write we are still writable (2047 bytes written).
|
||||||
// When this write succeeds we'll still be not writable (2 bytes outstanding).
|
// When this write succeeds we'll still be not writable (2 bytes outstanding).
|
||||||
connection.write(buffer.getSlice(at: 0, length: 2045)).whenComplete {
|
connection.write(buffer.getSlice(at: 0, length: 2045)).whenComplete { (_: Result<Void, Error>) in
|
||||||
XCTAssertEqual(writabilities, [false])
|
XCTAssertEqual(writabilities, [false])
|
||||||
XCTAssertFalse(connection.isWritable)
|
XCTAssertFalse(connection.isWritable)
|
||||||
}
|
}
|
||||||
|
|
@ -334,7 +339,7 @@ class NIOTSConnectionChannelTests: XCTestCase {
|
||||||
// Write d. After this write we are still writable (2048 bytes written).
|
// Write d. After this write we are still writable (2048 bytes written).
|
||||||
// When this write succeeds we'll become writable, but critically the promise fires before
|
// When this write succeeds we'll become writable, but critically the promise fires before
|
||||||
// the state change, so we'll *appear* to be unwritable.
|
// the state change, so we'll *appear* to be unwritable.
|
||||||
connection.write(buffer.getSlice(at: 0, length: 1)).whenComplete {
|
connection.write(buffer.getSlice(at: 0, length: 1)).whenComplete { (_: Result<Void, Error>) in
|
||||||
XCTAssertEqual(writabilities, [false])
|
XCTAssertEqual(writabilities, [false])
|
||||||
XCTAssertFalse(connection.isWritable)
|
XCTAssertFalse(connection.isWritable)
|
||||||
}
|
}
|
||||||
|
|
@ -344,7 +349,7 @@ class NIOTSConnectionChannelTests: XCTestCase {
|
||||||
// Write e. After this write we are now not writable (2049 bytes written).
|
// Write e. After this write we are now not writable (2049 bytes written).
|
||||||
// When this write succeeds we'll have already been writable, thanks to the previous
|
// When this write succeeds we'll have already been writable, thanks to the previous
|
||||||
// write.
|
// write.
|
||||||
connection.write(buffer.getSlice(at: 0, length: 1)).whenComplete {
|
connection.write(buffer.getSlice(at: 0, length: 1)).whenComplete { (_: Result<Void, Error>) in
|
||||||
XCTAssertEqual(writabilities, [false, true])
|
XCTAssertEqual(writabilities, [false, true])
|
||||||
XCTAssertTrue(connection.isWritable)
|
XCTAssertTrue(connection.isWritable)
|
||||||
|
|
||||||
|
|
@ -502,7 +507,7 @@ class NIOTSConnectionChannelTests: XCTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
let connectFuture = NIOTSConnectionBootstrap(group: self.group)
|
let connectFuture = NIOTSConnectionBootstrap(group: self.group)
|
||||||
.channelInitializer { channel in channel.eventLoop.newFailedFuture(error: MyError()) }
|
.channelInitializer { channel in channel.eventLoop.makeFailedFuture(error: MyError()) }
|
||||||
.connect(to: listener.localAddress!)
|
.connect(to: listener.localAddress!)
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
@ -581,7 +586,7 @@ class NIOTSConnectionChannelTests: XCTestCase {
|
||||||
XCTAssertNoThrow(try listener.close().wait())
|
XCTAssertNoThrow(try listener.close().wait())
|
||||||
}
|
}
|
||||||
|
|
||||||
let activePromise: EventLoopPromise<Void> = self.group.next().newPromise()
|
let activePromise: EventLoopPromise<Void> = self.group.next().makePromise()
|
||||||
|
|
||||||
let channel = try NIOTSConnectionBootstrap(group: self.group)
|
let channel = try NIOTSConnectionBootstrap(group: self.group)
|
||||||
.channelInitializer { channel in
|
.channelInitializer { channel in
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ final class ReadExpecter: ChannelInboundHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
func handlerAdded(ctx: ChannelHandlerContext) {
|
func handlerAdded(ctx: ChannelHandlerContext) {
|
||||||
self.readPromise = ctx.eventLoop.newPromise()
|
self.readPromise = ctx.eventLoop.makePromise()
|
||||||
}
|
}
|
||||||
|
|
||||||
func handlerRemoved(ctx: ChannelHandlerContext) {
|
func handlerRemoved(ctx: ChannelHandlerContext) {
|
||||||
|
|
@ -248,7 +248,7 @@ class NIOTSEndToEndTests: XCTestCase {
|
||||||
closeFutures.append(channel.closeFuture)
|
closeFutures.append(channel.closeFuture)
|
||||||
}
|
}
|
||||||
closeFutureGroup.leave()
|
closeFutureGroup.leave()
|
||||||
return channel.eventLoop.newSucceededFuture(result: ())
|
return channel.eventLoop.makeSucceededFuture(result: ())
|
||||||
}
|
}
|
||||||
.bind(host: "localhost", port: 0).wait()
|
.bind(host: "localhost", port: 0).wait()
|
||||||
defer {
|
defer {
|
||||||
|
|
@ -279,7 +279,7 @@ class NIOTSEndToEndTests: XCTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
func testAgreeOnRemoteLocalAddresses() throws {
|
func testAgreeOnRemoteLocalAddresses() throws {
|
||||||
let serverSideConnectionPromise: EventLoopPromise<Channel> = self.group.next().newPromise()
|
let serverSideConnectionPromise: EventLoopPromise<Channel> = self.group.next().makePromise()
|
||||||
let listener = try NIOTSListenerBootstrap(group: self.group)
|
let listener = try NIOTSListenerBootstrap(group: self.group)
|
||||||
.childChannelInitializer { channel in
|
.childChannelInitializer { channel in
|
||||||
serverSideConnectionPromise.succeed(result: channel)
|
serverSideConnectionPromise.succeed(result: channel)
|
||||||
|
|
@ -303,7 +303,7 @@ class NIOTSEndToEndTests: XCTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
func testHalfClosureSupported() throws {
|
func testHalfClosureSupported() throws {
|
||||||
let halfClosedPromise: EventLoopPromise<Void> = self.group.next().newPromise()
|
let halfClosedPromise: EventLoopPromise<Void> = self.group.next().makePromise()
|
||||||
let listener = try NIOTSListenerBootstrap(group: self.group)
|
let listener = try NIOTSListenerBootstrap(group: self.group)
|
||||||
.childChannelInitializer { channel in
|
.childChannelInitializer { channel in
|
||||||
channel.pipeline.add(handler: EchoHandler()).then { _ in
|
channel.pipeline.add(handler: EchoHandler()).then { _ in
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ class NIOTSEventLoopTest: XCTestCase {
|
||||||
firstTask.cancel()
|
firstTask.cancel()
|
||||||
}
|
}
|
||||||
let thirdTask = loop.scheduleTask(in: .milliseconds(50)) { }
|
let thirdTask = loop.scheduleTask(in: .milliseconds(50)) { }
|
||||||
firstTask.futureResult.whenComplete {
|
firstTask.futureResult.whenComplete { (_: Result<Void, Error>) in
|
||||||
let newNow = DispatchTime.now()
|
let newNow = DispatchTime.now()
|
||||||
XCTAssertLessThan(newNow.uptimeNanoseconds - now.uptimeNanoseconds,
|
XCTAssertLessThan(newNow.uptimeNanoseconds - now.uptimeNanoseconds,
|
||||||
300 * 1000 * 1000)
|
300 * 1000 * 1000)
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ class NIOTSListenerChannelTests: XCTestCase {
|
||||||
|
|
||||||
func testBindingToSocketAddressTraversesPipeline() throws {
|
func testBindingToSocketAddressTraversesPipeline() throws {
|
||||||
let bindRecordingHandler = BindRecordingHandler()
|
let bindRecordingHandler = BindRecordingHandler()
|
||||||
let target = try SocketAddress.newAddressResolving(host: "localhost", port: 0)
|
let target = try SocketAddress.makeAddressResolvingHost("localhost", port: 0)
|
||||||
let bindBootstrap = NIOTSListenerBootstrap(group: self.group)
|
let bindBootstrap = NIOTSListenerBootstrap(group: self.group)
|
||||||
.serverChannelInitializer { channel in channel.pipeline.add(handler: bindRecordingHandler)}
|
.serverChannelInitializer { channel in channel.pipeline.add(handler: bindRecordingHandler)}
|
||||||
|
|
||||||
|
|
@ -88,7 +88,7 @@ class NIOTSListenerChannelTests: XCTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
try self.group.next().submit {
|
try self.group.next().submit {
|
||||||
XCTAssertEqual(bindRecordingHandler.bindTargets, [try SocketAddress.newAddressResolving(host: "localhost", port: 0)])
|
XCTAssertEqual(bindRecordingHandler.bindTargets, [try SocketAddress.makeAddressResolvingHost("localhost", port: 0)])
|
||||||
XCTAssertEqual(bindRecordingHandler.endpointTargets, [])
|
XCTAssertEqual(bindRecordingHandler.endpointTargets, [])
|
||||||
}.wait()
|
}.wait()
|
||||||
}
|
}
|
||||||
|
|
@ -143,7 +143,7 @@ class NIOTSListenerChannelTests: XCTestCase {
|
||||||
struct MyError: Error { }
|
struct MyError: Error { }
|
||||||
|
|
||||||
let listenerFuture = NIOTSListenerBootstrap(group: self.group)
|
let listenerFuture = NIOTSListenerBootstrap(group: self.group)
|
||||||
.serverChannelInitializer { channel in channel.eventLoop.newFailedFuture(error: MyError()) }
|
.serverChannelInitializer { channel in channel.eventLoop.makeFailedFuture(error: MyError()) }
|
||||||
.bind(host: "localhost", port: 0)
|
.bind(host: "localhost", port: 0)
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
@ -160,8 +160,8 @@ class NIOTSListenerChannelTests: XCTestCase {
|
||||||
func testCanSafelyInvokeChannelsAcrossThreads() throws {
|
func testCanSafelyInvokeChannelsAcrossThreads() throws {
|
||||||
// This is a test that aims to trigger TSAN violations.
|
// This is a test that aims to trigger TSAN violations.
|
||||||
let childGroup = NIOTSEventLoopGroup(loopCount: 2)
|
let childGroup = NIOTSEventLoopGroup(loopCount: 2)
|
||||||
let childChannelPromise: EventLoopPromise<Channel> = childGroup.next().newPromise()
|
let childChannelPromise: EventLoopPromise<Channel> = childGroup.next().makePromise()
|
||||||
let activePromise: EventLoopPromise<Void> = childGroup.next().newPromise()
|
let activePromise: EventLoopPromise<Void> = childGroup.next().makePromise()
|
||||||
|
|
||||||
let listener = try NIOTSListenerBootstrap(group: self.group, childGroup: childGroup)
|
let listener = try NIOTSListenerBootstrap(group: self.group, childGroup: childGroup)
|
||||||
.childChannelInitializer { channel in
|
.childChannelInitializer { channel in
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue