Skip to content

Make async/await available on older Apple Platforms #527

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Dec 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Sources/AsyncHTTPClient/AsyncAwait/HTTPClient+execute.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@
//
//===----------------------------------------------------------------------===//

#if compiler(>=5.5) && canImport(_Concurrency)
#if compiler(>=5.5.2) && canImport(_Concurrency)
import struct Foundation.URL
import Logging
import NIOCore
import NIOHTTP1

@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
extension HTTPClient {
/// Execute arbitrary HTTP requests.
///
Expand All @@ -41,7 +41,7 @@ extension HTTPClient {
}
}

@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
extension HTTPClient {
private func executeAndFollowRedirectsIfNeeded(
_ request: HTTPClientRequest,
Expand Down Expand Up @@ -124,7 +124,7 @@ extension HTTPClient {
/// There is currently no good way to asynchronously cancel an object that is initiated inside the `body` closure of `with*Continuation`.
/// As a workaround we use `TransactionCancelHandler` which will take care of the race between instantiation of `Transaction`
/// in the `body` closure and cancelation from the `onCancel` closure of `withTaskCancellationHandler`.
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
private actor TransactionCancelHandler {
enum CancelReason {
/// swift concurrency task was canceled
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
//
//===----------------------------------------------------------------------===//

#if compiler(>=5.5) && canImport(_Concurrency)
#if compiler(>=5.5.2) && canImport(_Concurrency)
import struct Foundation.URL
import NIOHTTP1

@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
extension HTTPClientRequest {
struct Prepared {
var url: URL
Expand All @@ -27,7 +27,7 @@ extension HTTPClientRequest {
}
}

@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
extension HTTPClientRequest.Prepared {
init(_ request: HTTPClientRequest) throws {
guard let url = URL(string: request.url) else {
Expand Down Expand Up @@ -58,7 +58,7 @@ extension HTTPClientRequest.Prepared {
}
}

@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
extension RequestBodyLength {
init(_ body: HTTPClientRequest.Body?) {
switch body?.mode {
Expand All @@ -74,7 +74,7 @@ extension RequestBodyLength {
}
}

@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
extension HTTPClientRequest.Prepared {
func followingRedirect(to redirectURL: URL, status: HTTPResponseStatus) -> HTTPClientRequest {
let (method, headers, body) = transformRequestForRedirect(
Expand Down
10 changes: 5 additions & 5 deletions Sources/AsyncHTTPClient/AsyncAwait/HTTPClientRequest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
//
//===----------------------------------------------------------------------===//

#if compiler(>=5.5) && canImport(_Concurrency)
#if compiler(>=5.5.2) && canImport(_Concurrency)
import NIOCore
import NIOHTTP1

@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
struct HTTPClientRequest {
var url: String
var method: HTTPMethod
Expand All @@ -32,7 +32,7 @@ struct HTTPClientRequest {
}
}

@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
extension HTTPClientRequest {
struct Body {
internal enum Mode {
Expand All @@ -49,7 +49,7 @@ extension HTTPClientRequest {
}
}

@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
extension HTTPClientRequest.Body {
static func byteBuffer(_ byteBuffer: ByteBuffer) -> Self {
self.init(.byteBuffer(byteBuffer))
Expand Down Expand Up @@ -131,7 +131,7 @@ extension HTTPClientRequest.Body {
}
}

@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
extension Optional where Wrapped == HTTPClientRequest.Body {
internal var canBeConsumedMultipleTimes: Bool {
switch self?.mode {
Expand Down
10 changes: 5 additions & 5 deletions Sources/AsyncHTTPClient/AsyncAwait/HTTPClientResponse.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
//
//===----------------------------------------------------------------------===//

#if compiler(>=5.5) && canImport(_Concurrency)
#if compiler(>=5.5.2) && canImport(_Concurrency)
import NIOCore
import NIOHTTP1

@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
struct HTTPClientResponse {
var version: HTTPVersion
var status: HTTPResponseStatus
Expand Down Expand Up @@ -46,7 +46,7 @@ struct HTTPClientResponse {
}
}

@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
extension HTTPClientResponse.Body: AsyncSequence {
typealias Element = ByteBuffer
typealias AsyncIterator = Iterator
Expand All @@ -70,7 +70,7 @@ extension HTTPClientResponse.Body: AsyncSequence {
}
}

@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
extension HTTPClientResponse.Body {
/// The purpose of this object is to inform the transaction about the response body being deinitialized.
/// If the users has not called `makeAsyncIterator` on the body, before it is deinited, the http
Expand All @@ -88,7 +88,7 @@ extension HTTPClientResponse.Body {
}
}

@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
extension HTTPClientResponse.Body {
internal class IteratorStream {
struct ID: Hashable {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//
#if compiler(>=5.5) && canImport(_Concurrency)
#if compiler(>=5.5.2) && canImport(_Concurrency)
import Logging
import NIOCore
import NIOHTTP1

@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
extension Transaction {
struct StateMachine {
struct ExecutionContext {
Expand Down
10 changes: 5 additions & 5 deletions Sources/AsyncHTTPClient/AsyncAwait/Transaction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@
//
//===----------------------------------------------------------------------===//

#if compiler(>=5.5) && canImport(_Concurrency)
#if compiler(>=5.5.2) && canImport(_Concurrency)
import Logging
import NIOConcurrencyHelpers
import NIOCore
import NIOHTTP1
import NIOSSL

@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
final class Transaction: @unchecked Sendable {
let logger: Logger

Expand Down Expand Up @@ -145,7 +145,7 @@ final class Transaction: @unchecked Sendable {

// MARK: - Protocol Methods -

@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
extension Transaction: HTTPSchedulableRequest {
var poolKey: ConnectionPool.Key { self.request.poolKey }
var tlsConfiguration: TLSConfiguration? { return nil }
Expand All @@ -158,7 +158,7 @@ extension Transaction: HTTPSchedulableRequest {
}
}

@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
extension Transaction: HTTPExecutableRequest {
var requestHead: HTTPRequestHead { self.request.head }

Expand Down Expand Up @@ -316,7 +316,7 @@ extension Transaction: HTTPExecutableRequest {
}
}

@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
extension Transaction {
func responseBodyDeinited() {
let deinitedAction = self.stateLock.withLock {
Expand Down
58 changes: 29 additions & 29 deletions Tests/AsyncHTTPClientTests/AsyncAwaitEndToEndTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ private func makeDefaultHTTPClient(

final class AsyncAwaitEndToEndTests: XCTestCase {
func testSimpleGet() {
#if compiler(>=5.5) && canImport(_Concurrency)
guard #available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) else { return }
#if compiler(>=5.5.2) && canImport(_Concurrency)
guard #available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) else { return }
XCTAsyncTest {
let bin = HTTPBin(.http2(compress: false))
defer { XCTAssertNoThrow(try bin.shutdown()) }
Expand All @@ -57,8 +57,8 @@ final class AsyncAwaitEndToEndTests: XCTestCase {
}

func testSimplePost() {
#if compiler(>=5.5) && canImport(_Concurrency)
guard #available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) else { return }
#if compiler(>=5.5.2) && canImport(_Concurrency)
guard #available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) else { return }
XCTAsyncTest {
let bin = HTTPBin(.http2(compress: false))
defer { XCTAssertNoThrow(try bin.shutdown()) }
Expand All @@ -80,8 +80,8 @@ final class AsyncAwaitEndToEndTests: XCTestCase {
}

func testPostWithByteBuffer() {
#if compiler(>=5.5) && canImport(_Concurrency)
guard #available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) else { return }
#if compiler(>=5.5.2) && canImport(_Concurrency)
guard #available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) else { return }
XCTAsyncTest {
let bin = HTTPBin(.http2(compress: false)) { _ in HTTPEchoHandler() }
defer { XCTAssertNoThrow(try bin.shutdown()) }
Expand All @@ -105,8 +105,8 @@ final class AsyncAwaitEndToEndTests: XCTestCase {
}

func testPostWithSequenceOfUInt8() {
#if compiler(>=5.5) && canImport(_Concurrency)
guard #available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) else { return }
#if compiler(>=5.5.2) && canImport(_Concurrency)
guard #available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) else { return }
XCTAsyncTest {
let bin = HTTPBin(.http2(compress: false)) { _ in HTTPEchoHandler() }
defer { XCTAssertNoThrow(try bin.shutdown()) }
Expand All @@ -130,8 +130,8 @@ final class AsyncAwaitEndToEndTests: XCTestCase {
}

func testPostWithCollectionOfUInt8() {
#if compiler(>=5.5) && canImport(_Concurrency)
guard #available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) else { return }
#if compiler(>=5.5.2) && canImport(_Concurrency)
guard #available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) else { return }
XCTAsyncTest {
let bin = HTTPBin(.http2(compress: false)) { _ in HTTPEchoHandler() }
defer { XCTAssertNoThrow(try bin.shutdown()) }
Expand All @@ -155,8 +155,8 @@ final class AsyncAwaitEndToEndTests: XCTestCase {
}

func testPostWithRandomAccessCollectionOfUInt8() {
#if compiler(>=5.5) && canImport(_Concurrency)
guard #available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) else { return }
#if compiler(>=5.5.2) && canImport(_Concurrency)
guard #available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) else { return }
XCTAsyncTest {
let bin = HTTPBin(.http2(compress: false)) { _ in HTTPEchoHandler() }
defer { XCTAssertNoThrow(try bin.shutdown()) }
Expand All @@ -180,8 +180,8 @@ final class AsyncAwaitEndToEndTests: XCTestCase {
}

func testPostWithAsyncSequenceOfByteBuffers() {
#if compiler(>=5.5) && canImport(_Concurrency)
guard #available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) else { return }
#if compiler(>=5.5.2) && canImport(_Concurrency)
guard #available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) else { return }
XCTAsyncTest {
let bin = HTTPBin(.http2(compress: false)) { _ in HTTPEchoHandler() }
defer { XCTAssertNoThrow(try bin.shutdown()) }
Expand Down Expand Up @@ -209,8 +209,8 @@ final class AsyncAwaitEndToEndTests: XCTestCase {
}

func testPostWithAsyncSequenceOfUInt8() {
#if compiler(>=5.5) && canImport(_Concurrency)
guard #available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) else { return }
#if compiler(>=5.5.2) && canImport(_Concurrency)
guard #available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) else { return }
XCTAsyncTest {
let bin = HTTPBin(.http2(compress: false)) { _ in HTTPEchoHandler() }
defer { XCTAssertNoThrow(try bin.shutdown()) }
Expand All @@ -234,8 +234,8 @@ final class AsyncAwaitEndToEndTests: XCTestCase {
}

func testPostWithFragmentedAsyncSequenceOfByteBuffers() {
#if compiler(>=5.5) && canImport(_Concurrency)
guard #available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) else { return }
#if compiler(>=5.5.2) && canImport(_Concurrency)
guard #available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) else { return }
XCTAsyncTest {
let bin = HTTPBin(.http2(compress: false)) { _ in HTTPEchoHandler() }
defer { XCTAssertNoThrow(try bin.shutdown()) }
Expand Down Expand Up @@ -276,8 +276,8 @@ final class AsyncAwaitEndToEndTests: XCTestCase {
}

func testPostWithFragmentedAsyncSequenceOfLargeByteBuffers() {
#if compiler(>=5.5) && canImport(_Concurrency)
guard #available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) else { return }
#if compiler(>=5.5.2) && canImport(_Concurrency)
guard #available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) else { return }
XCTAsyncTest {
let bin = HTTPBin(.http2(compress: false)) { _ in HTTPEchoHandler() }
defer { XCTAssertNoThrow(try bin.shutdown()) }
Expand Down Expand Up @@ -319,8 +319,8 @@ final class AsyncAwaitEndToEndTests: XCTestCase {
}

func testCanceling() {
#if compiler(>=5.5) && canImport(_Concurrency)
guard #available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) else { return }
#if compiler(>=5.5.2) && canImport(_Concurrency)
guard #available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) else { return }
XCTAsyncTest(timeout: 5) {
let bin = HTTPBin(.http2(compress: false))
defer { XCTAssertNoThrow(try bin.shutdown()) }
Expand All @@ -344,8 +344,8 @@ final class AsyncAwaitEndToEndTests: XCTestCase {
}

func testDeadline() {
#if compiler(>=5.5) && canImport(_Concurrency)
guard #available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) else { return }
#if compiler(>=5.5.2) && canImport(_Concurrency)
guard #available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) else { return }
XCTAsyncTest(timeout: 5) {
let bin = HTTPBin(.http2(compress: false))
defer { XCTAssertNoThrow(try bin.shutdown()) }
Expand All @@ -365,8 +365,8 @@ final class AsyncAwaitEndToEndTests: XCTestCase {
}

func testImmediateDeadline() {
#if compiler(>=5.5) && canImport(_Concurrency)
guard #available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) else { return }
#if compiler(>=5.5.2) && canImport(_Concurrency)
guard #available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) else { return }
XCTAsyncTest(timeout: 5) {
let bin = HTTPBin(.http2(compress: false))
defer { XCTAssertNoThrow(try bin.shutdown()) }
Expand All @@ -386,8 +386,8 @@ final class AsyncAwaitEndToEndTests: XCTestCase {
}

func testInvalidURL() {
#if compiler(>=5.5) && canImport(_Concurrency)
guard #available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) else { return }
#if compiler(>=5.5.2) && canImport(_Concurrency)
guard #available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) else { return }
XCTAsyncTest(timeout: 5) {
let client = makeDefaultHTTPClient()
defer { XCTAssertNoThrow(try client.syncShutdown()) }
Expand All @@ -402,7 +402,7 @@ final class AsyncAwaitEndToEndTests: XCTestCase {
}
}

#if compiler(>=5.5) && canImport(_Concurrency)
#if compiler(>=5.5.2) && canImport(_Concurrency)
extension AsyncSequence where Element == ByteBuffer {
func collect() async rethrows -> ByteBuffer {
try await self.reduce(into: ByteBuffer()) { accumulatingBuffer, nextBuffer in
Expand Down
4 changes: 2 additions & 2 deletions Tests/AsyncHTTPClientTests/AsyncTestHelpers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
//
//===----------------------------------------------------------------------===//

#if swift(>=5.5) && canImport(_Concurrency)
#if compiler(>=5.5.2) && canImport(_Concurrency)
import NIOConcurrencyHelpers
import NIOCore

@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only tests, but presumably the #if swift above needs to be updated too?

class AsyncSequenceWriter<Element>: AsyncSequence {
typealias AsyncIterator = Iterator

Expand Down
Loading