Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for streaming on recent Darwin platforms (#24)
### Motivation Recently, the `ClientTransport` protocol was updated to be in terms of `HTTPBody`, which is an `AsyncSequence<ArraySlice<UInt8>>`. Until now, the URLSession transport has buffered the request and response bodies in memory. This PR seeks to bring streaming support to recent Darwin platforms. ### Modifications On new enough Darwin platforms[^1], use URLSession delegate to perform bidirectional streaming with backpressure. Request body backpressure is provided by the use of `StreamDelegate` with a bound stream pair. Response body backpressure is provided by the use of `AsyncBackpressuredStream` which allows for a high and low watermark to suspend and resume the URLSession task. [^1]: macOS 12, iOS 15, tvOS 15, watchOS 8 In more detail: - Vendor internal `AsyncBackpressuredStream` implementation from SE-0406. - Add `HTTPBodyOutputStreamBridge` which provides the `OutputStreamDelegate` required to bridge the `AsyncSequence`-based `HTTPBody` to an `OutputStream`. - Add `BidirectionalStreamingURLSessionDelegate` which makes use of `HTTPBodyOutputStreamBridge` for streaming request bodies and also uses the delegate callbacks to bridge the response body to `HTTPBody`. - Add `URLSession.bidirectionalStreamingRequest(...) async throws`, which provides a high-level URLSession-like API for setting up the appropriate URLSession task and delegate. - Add `URLSession.bufferedRequest(...) async throws` to provide a similar interfaces on platforms that don't support the streaming APIs on which we depend. - Add internal `enum URLSessionTransport.Configuration.Implementation` to control whether to use buffered or streaming implementation. - Detect appropriate implementation depending on the platform. ### Result - On new enough Darwin platforms[^1], streaming will be used. ### Test Plan - Add a set of tests that run with both buffered and streaming implementation on platforms that support streaming. - Add a set of tests that only run on platforms that support streaming, to test request flows only possible with streaming. However, it's worth noting that our CI only runs on Linux, so we won't be testing the majority of this new feature in CI.
- Loading branch information