Skip to content

Commit

Permalink
Throw cancellation errors when async observation is cancelled
Browse files Browse the repository at this point in the history
  • Loading branch information
vsanthanam committed Mar 31, 2024
1 parent 3262e24 commit d44e286
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,20 @@ public extension NetworkMonitor {
/// Retrieve the latest known network path using [Swift Concurrency](https://docs.swift.org/swift-book/LanguageGuide/Concurrency.html)
///
/// ```swift
/// func updateReachability() async {
/// let path = await NetworkMonitor.networkPath
/// func updateReachability() async throws {
/// let path = try await NetworkMonitor.networkPath
/// // Do something with `path`
/// }
/// ```
static var networkPath: NWPath {
get async {
await withUnsafeContinuation { continuation in
get async throws {
try await withUnsafeThrowingContinuation { continuation in
NetworkMonitor.networkPath { path in
continuation.resume(returning: path)
if Task.isCancelled {
continuation.resume(throwing: CancellationError())
} else {
continuation.resume(returning: path)
}
}
}
}
Expand All @@ -55,7 +59,7 @@ public extension NetworkMonitor {
/// // Do something with `path`
/// }
/// ```
static var networkPathUpdates: AsyncStream<NWPath> {
static var networkPathUpdates: AsyncThrowingStream<NWPath, any Error> {
stream(.init())
}

Expand All @@ -68,7 +72,7 @@ public extension NetworkMonitor {
/// // Do something with `path`
/// }
/// ```
static func networkPathUpdates(requiringInterfaceType interfaceType: NWInterface.InterfaceType) -> AsyncStream<NWPath> {
static func networkPathUpdates(requiringInterfaceType interfaceType: NWInterface.InterfaceType) -> AsyncThrowingStream<NWPath, any Error> {
stream(.init(requiredInterfaceType: interfaceType))
}

Expand All @@ -82,16 +86,21 @@ public extension NetworkMonitor {
/// }
/// ```
@available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)
static func networkPathUpdates(prohibitingInterfaceTypes interfaceTypes: [NWInterface.InterfaceType]) -> AsyncStream<NWPath> {
static func networkPathUpdates(prohibitingInterfaceTypes interfaceTypes: [NWInterface.InterfaceType]) -> AsyncThrowingStream<NWPath, any Error> {
stream(.init(prohibitedInterfaceTypes: interfaceTypes))
}
}

@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
private func stream(_ monitor: NWPathMonitor) -> AsyncStream<NWPath> {
.init(bufferingPolicy: .bufferingNewest(1)) { continuation in
private func stream(_ monitor: NWPathMonitor) -> AsyncThrowingStream<NWPath, any Error> {
.init { continuation in
monitor.pathUpdateHandler = { path in
continuation.yield(path)
if Task.isCancelled {
monitor.cancel()
continuation.finish(throwing: CancellationError())
} else {
continuation.yield(path)
}
}
monitor.start(queue: .networkMonitorQueue)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,9 @@ public final class NetworkMonitor {
}
} else if #available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) {
Task {
completionHandler(path)
await MainActor.run {
completionHandler(path)
}
}
} else {
DispatchQueue.main.async {
Expand Down

0 comments on commit d44e286

Please sign in to comment.