swift-nio-transport-services/Sources/NIOTransportServices/NIOTSNetworkEvents.swift

133 lines
5.8 KiB
Swift

//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftNIO open source project
//
// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//
#if canImport(Network)
import Network
import NIOCore
/// A tag protocol that can be used to cover all network events emitted by `NIOTransportServices`.
///
/// Users are strongly encouraged not to conform their own types to this protocol.
@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *)
public protocol NIOTSNetworkEvent: Equatable, _NIOPreconcurrencySendable {}
@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *)
public enum NIOTSNetworkEvents: Sendable {
/// ``BetterPathAvailable`` is fired whenever the OS has informed NIO that there is a better
/// path available to the endpoint that this `Channel` is currently connected to,
/// e.g. the current connection is using an expensive cellular connection and
/// a cheaper WiFi connection has become available.
///
/// If you can handle this event, you should make a new connection attempt, and then
/// transfer your work to that connection before closing this one.
public struct BetterPathAvailable: NIOTSNetworkEvent {
/// Create a new ``NIOTSNetworkEvents/BetterPathAvailable`` event.
public init() {}
}
/// ``BetterPathUnavailable`` is fired when the OS has informed NIO that no better path to the
/// to the remote endpoint than the one currently being used by this `Channel` is
/// currently available.
public struct BetterPathUnavailable: NIOTSNetworkEvent {
/// Create a new ``NIOTSNetworkEvents/BetterPathUnavailable`` event.
public init() {}
}
/// ``ViabilityUpdate`` is triggered when the OS informs NIO that communication
/// with the remote endpoint is possible, indicating that the connection is viable.
public struct ViabilityUpdate: NIOTSNetworkEvent {
/// The current viability for the connection
public var isViable: Bool
/// Create a new ``NIOTSNetworkEvents/ViabilityUpdate`` event.
public init(isViable: Bool) {
self.isViable = isViable
}
}
/// ``PathChanged`` is fired whenever the OS has informed NIO that a new path is in use
/// for this `Channel`.
public struct PathChanged: NIOTSNetworkEvent {
/// The new path for this `Channel`.
public let newPath: NWPath
/// Create a new ``NIOTSNetworkEvents/PathChanged`` event.
public init(newPath: NWPath) {
self.newPath = newPath
}
}
/// ``ConnectToNWEndpoint`` is fired as an outbound event when NIO would like to ask Network.framework
/// to handle the connection logic (e.g. its own DNS resolution and happy eyeballs racing).
public struct ConnectToNWEndpoint: NIOTSNetworkEvent {
/// The endpoint to which we want to connect.
public let endpoint: NWEndpoint
/// Create a new ``NIOTSNetworkEvents/ConnectToNWEndpoint`` event.
public init(endpoint: NWEndpoint) {
self.endpoint = endpoint
}
}
/// ``BindToNWEndpoint`` is fired as an outbound event when NIO would like to ask Network.framework
/// to handle the binding logic (e.g. its own support for bonjour and interface selection).
public struct BindToNWEndpoint: NIOTSNetworkEvent {
/// The endpoint to which we want to bind.
public let endpoint: NWEndpoint
/// Create a new ``NIOTSNetworkEvents/BindToNWEndpoint`` event.
public init(endpoint: NWEndpoint) {
self.endpoint = endpoint
}
}
/// ``WaitingForConnectivity`` is fired when when the OS has informed NIO that it cannot immediately connect
/// to the remote endpoint, but that it is possible that changes in network conditions may
/// allow connection in future. This can occur in cases where the route is not currently
/// satisfiable (e.g. because airplane mode is on, or because the app is forbidden from using cellular)
/// but where a change in network state may allow the connection.
public struct WaitingForConnectivity: NIOTSNetworkEvent {
/// The reason the connection couldn't be established at this time.
///
/// Note that these reasons are _not fatal_: applications are strongly advised not to treat them
/// as fatal, and instead to use them as information to inform UI decisions.
public var transientError: NWError
/// Create a new ``NIOTSNetworkEvents/WaitingForConnectivity`` event.
public init(transientError: NWError) {
self.transientError = transientError
}
}
}
// Network.framework has not adopted `Sendable` yet.
// We therefore need to import it with `@preconcurrency`.
@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *)
extension NIOTSNetworkEvents.BetterPathAvailable: Sendable {}
@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *)
extension NIOTSNetworkEvents.BetterPathUnavailable: Sendable {}
@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *)
extension NIOTSNetworkEvents.ViabilityUpdate: Sendable {}
@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *)
extension NIOTSNetworkEvents.PathChanged: Sendable {}
@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *)
extension NIOTSNetworkEvents.ConnectToNWEndpoint: Sendable {}
@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *)
extension NIOTSNetworkEvents.BindToNWEndpoint: Sendable {}
@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *)
extension NIOTSNetworkEvents.WaitingForConnectivity: Sendable {}
#endif