Skip to content

Instantly share code, notes, and snippets.

@swhitty
Created April 19, 2023 06:35
Show Gist options
  • Save swhitty/20ed800baf26a36f0ab8ba16855cdf41 to your computer and use it in GitHub Desktop.
Save swhitty/20ed800baf26a36f0ab8ba16855cdf41 to your computer and use it in GitHub Desktop.
// ThrowingTaskGroup.waitForAll() behaviour was fixed in Swift 5.9
// This backports the Swift 5.9 behaviour to earlier versions
// https://github.com/apple/swift/pull/63016
public extension ThrowingTaskGroup {
#if compiler(>=5.9)
@available(*, deprecated, renamed: "waitForAll")
#endif
mutating func waitForAllFix() async throws {
var firstError: Error? = nil
// Make sure we loop until all child tasks have completed
while !isEmpty {
do {
while let _ = try await next() {}
} catch {
// Upon error throws, capture the first one
if firstError == nil {
firstError = error
}
}
}
if let firstError {
throw firstError
}
}
}
@swhitty
Copy link
Author

swhitty commented Apr 19, 2023

Test with the following. "Gone Fishing 🐠" will be printed every time.

try? await withThrowingTaskGroup(of: Void.self) { group in
  group.addTask { throw CancellationError() }
  group.addTask {
    try await Task.sleep(nanoseconds: 1_000_000_000)
    print("Gone Fishing 🐠")
  }

  try await group.waitForAllFix()
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment