@@ -191,26 +191,70 @@ extension HTTPClientResponse.Body: AsyncSequence {
191
191
@available ( macOS 12 . 0 , iOS 15 . 0 , watchOS 8 . 0 , tvOS 15 . 0 , * )
192
192
extension HTTPClient {
193
193
func execute( _ request: HTTPClientRequest , deadline: NIODeadline , logger: Logger ) async throws -> HTTPClientResponse {
194
- let bag = try AsyncRequestBag (
195
- request: request,
196
- requestOptions: . init( idleReadTimeout: nil ) ,
197
- logger: logger,
198
- connectionDeadline: . now( ) + . seconds( 10 ) ,
199
- preferredEventLoop: self . eventLoopGroup. next ( )
200
- )
201
-
202
- return try await withTaskCancellationHandler {
203
- bag. cancel ( )
204
- } operation: { ( ) -> HTTPClientResponse in
205
- // first register the completion
206
- async let result = bag. result ( )
207
-
208
- // second throw it onto the connection pool for execution
209
- self . poolManager. executeRequest ( bag)
210
-
211
- // third await result
212
- return try await result
194
+ actor SwiftCancellationHandlingSucksAsFuck {
195
+
196
+ enum State {
197
+ case initialized
198
+ case register( AsyncRequestBag )
199
+ case cancelled
200
+ }
201
+
202
+ private var state : State = . initialized
203
+
204
+ init ( ) { }
205
+
206
+ func registerRequestBag( _ bag: AsyncRequestBag ) {
207
+ switch self . state {
208
+ case . initialized:
209
+ self . state = . register( bag)
210
+ case . cancelled:
211
+ bag. cancel ( )
212
+ case . register:
213
+ preconditionFailure ( )
214
+ }
215
+ }
216
+
217
+ func cancel( ) {
218
+ switch self . state {
219
+ case . register( let bag) :
220
+ self . state = . cancelled
221
+ bag. cancel ( )
222
+ case . cancelled:
223
+ break
224
+ case . initialized:
225
+ self . state = . cancelled
226
+ }
227
+ }
213
228
}
229
+
230
+ let cancelHandler = SwiftCancellationHandlingSucksAsFuck ( )
231
+
232
+ //let onCancel: @Sendable () -> () =
233
+
234
+ return try await withTaskCancellationHandler ( operation: { ( ) async throws -> HTTPClientResponse in
235
+ try await withUnsafeThrowingContinuation {
236
+ ( continuation: UnsafeContinuation < HTTPClientResponse , Swift . Error > ) -> Void in
237
+
238
+ let bag = try ! AsyncRequestBag (
239
+ request: request,
240
+ requestOptions: . init( idleReadTimeout: nil ) ,
241
+ logger: logger,
242
+ connectionDeadline: . now( ) + . seconds( 10 ) ,
243
+ preferredEventLoop: self . eventLoopGroup. next ( ) ,
244
+ responseContinuation: continuation
245
+ )
246
+
247
+ _Concurrency. Task {
248
+ await cancelHandler. registerRequestBag ( bag)
249
+ }
250
+
251
+ self . poolManager. executeRequest ( bag)
252
+ }
253
+ } , onCancel: {
254
+ _Concurrency. Task {
255
+ await cancelHandler. cancel ( )
256
+ }
257
+ } )
214
258
}
215
259
}
216
260
0 commit comments