Commit 686df72
authored
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.1 parent 70b63ef commit 686df72
File tree
20 files changed
+3914
-184
lines changed- Sources/OpenAPIURLSession
- AsyncBackpressuredStream
- Documentation.docc
- URLSessionBidirectionalStreaming
- Tests/OpenAPIURLSessionTests
- AsyncBackpressuredStreamTests
- URLSessionBidirectionalStreamingTests
20 files changed
+3914
-184
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
32 | 32 | | |
33 | 33 | | |
34 | 34 | | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
24 | 24 | | |
25 | 25 | | |
26 | 26 | | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
27 | 34 | | |
28 | 35 | | |
| 36 | + | |
29 | 37 | | |
30 | 38 | | |
31 | 39 | | |
| |||
40 | 48 | | |
41 | 49 | | |
42 | 50 | | |
| 51 | + | |
43 | 52 | | |
44 | 53 | | |
45 | 54 | | |
46 | 55 | | |
47 | 56 | | |
| 57 | + | |
48 | 58 | | |
49 | 59 | | |
50 | 60 | | |
51 | 61 | | |
52 | 62 | | |
53 | 63 | | |
54 | | - | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
55 | 68 | | |
56 | 69 | | |
57 | 70 | | |
58 | 71 | | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
12 | | - | |
13 | | - | |
14 | | - | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
15 | 20 | | |
16 | 21 | | |
17 | 22 | | |
| |||
0 commit comments