@@ -41,7 +41,7 @@ final class TransactionTests: XCTestCase {
4141 guard let preparedRequest = maybePreparedRequest else {
4242 return XCTFail ( " Expected to have a request here. " )
4343 }
44- let ( transaction, responseTask) = Transaction . makeWithResultTask (
44+ let ( transaction, responseTask) = await Transaction . makeWithResultTask (
4545 request: preparedRequest,
4646 preferredEventLoop: embeddedEventLoop
4747 )
@@ -78,7 +78,7 @@ final class TransactionTests: XCTestCase {
7878 guard let preparedRequest = maybePreparedRequest else {
7979 return
8080 }
81- let ( transaction, responseTask) = Transaction . makeWithResultTask (
81+ let ( transaction, responseTask) = await Transaction . makeWithResultTask (
8282 request: preparedRequest,
8383 preferredEventLoop: embeddedEventLoop
8484 )
@@ -141,7 +141,7 @@ final class TransactionTests: XCTestCase {
141141 guard let preparedRequest = maybePreparedRequest else {
142142 return
143143 }
144- var tuple : ( Transaction , Task < HTTPClientResponse , Error > ) ! = Transaction . makeWithResultTask (
144+ var tuple : ( Transaction , Task < HTTPClientResponse , Error > ) ! = await Transaction . makeWithResultTask (
145145 request: preparedRequest,
146146 preferredEventLoop: embeddedEventLoop
147147 )
@@ -196,7 +196,7 @@ final class TransactionTests: XCTestCase {
196196 guard let preparedRequest = maybePreparedRequest else {
197197 return XCTFail ( " Expected to have a request here. " )
198198 }
199- let ( transaction, responseTask) = Transaction . makeWithResultTask (
199+ let ( transaction, responseTask) = await Transaction . makeWithResultTask (
200200 request: preparedRequest,
201201 preferredEventLoop: embeddedEventLoop
202202 )
@@ -282,7 +282,7 @@ final class TransactionTests: XCTestCase {
282282 guard let preparedRequest = maybePreparedRequest else {
283283 return XCTFail ( " Expected to have a request here. " )
284284 }
285- let ( transaction, responseTask) = Transaction . makeWithResultTask (
285+ let ( transaction, responseTask) = await Transaction . makeWithResultTask (
286286 request: preparedRequest,
287287 preferredEventLoop: eventLoopGroup. next ( )
288288 )
@@ -324,7 +324,7 @@ final class TransactionTests: XCTestCase {
324324 guard let preparedRequest = maybePreparedRequest else {
325325 return XCTFail ( " Expected to have a request here. " )
326326 }
327- let ( transaction, responseTask) = Transaction . makeWithResultTask (
327+ let ( transaction, responseTask) = await Transaction . makeWithResultTask (
328328 request: preparedRequest,
329329 preferredEventLoop: embeddedEventLoop
330330 )
@@ -366,7 +366,7 @@ final class TransactionTests: XCTestCase {
366366 guard let preparedRequest = maybePreparedRequest else {
367367 return XCTFail ( " Expected to have a request here. " )
368368 }
369- let ( transaction, responseTask) = Transaction . makeWithResultTask (
369+ let ( transaction, responseTask) = await Transaction . makeWithResultTask (
370370 request: preparedRequest,
371371 preferredEventLoop: embeddedEventLoop
372372 )
@@ -397,7 +397,7 @@ final class TransactionTests: XCTestCase {
397397 func testResponseStreamFails( ) {
398398 #if compiler(>=5.5.2) && canImport(_Concurrency)
399399 guard #available( macOS 10 . 15 , iOS 13 . 0 , watchOS 6 . 0 , tvOS 13 . 0 , * ) else { return }
400- XCTAsyncTest {
400+ XCTAsyncTest ( timeout : 30 ) {
401401 let embeddedEventLoop = EmbeddedEventLoop ( )
402402 defer { XCTAssertNoThrow ( try embeddedEventLoop. syncShutdownGracefully ( ) ) }
403403
@@ -409,7 +409,7 @@ final class TransactionTests: XCTestCase {
409409 guard let preparedRequest = maybePreparedRequest else {
410410 return
411411 }
412- let ( transaction, responseTask) = Transaction . makeWithResultTask (
412+ let ( transaction, responseTask) = await Transaction . makeWithResultTask (
413413 request: preparedRequest,
414414 preferredEventLoop: embeddedEventLoop
415415 )
@@ -427,6 +427,7 @@ final class TransactionTests: XCTestCase {
427427 transaction. receiveResponseHead ( responseHead)
428428
429429 let response = try await responseTask. value
430+
430431 XCTAssertEqual ( response. status, responseHead. status)
431432 XCTAssertEqual ( response. headers, responseHead. headers)
432433 XCTAssertEqual ( response. version, responseHead. version)
@@ -438,6 +439,7 @@ final class TransactionTests: XCTestCase {
438439 XCTAssertNoThrow ( try executor. receiveResponseDemand ( ) )
439440 executor. resetResponseStreamDemandSignal ( )
440441 transaction. receiveResponseBodyParts ( [ ByteBuffer ( integer: 123 ) ] )
442+
441443 let result = try await part1
442444 XCTAssertEqual ( result, ByteBuffer ( integer: 123 ) )
443445
@@ -493,7 +495,7 @@ final class TransactionTests: XCTestCase {
493495 guard let preparedRequest = maybePreparedRequest else {
494496 return
495497 }
496- let ( transaction, responseTask) = Transaction . makeWithResultTask (
498+ let ( transaction, responseTask) = await Transaction . makeWithResultTask (
497499 request: preparedRequest,
498500 preferredEventLoop: eventLoopGroup. next ( )
499501 )
@@ -553,6 +555,45 @@ actor SharedIterator<Iterator: AsyncIteratorProtocol> {
553555 }
554556}
555557
558+ /// non fail-able promise that only supports one observer
559+ @available ( macOS 10 . 15 , iOS 13 . 0 , watchOS 6 . 0 , tvOS 13 . 0 , * )
560+ fileprivate actor Promise < Value> {
561+ private enum State {
562+ case initialised
563+ case fulfilled( Value )
564+ }
565+
566+ private var state : State = . initialised
567+
568+ private var observer : CheckedContinuation < Value , Never > ?
569+
570+ init ( ) { }
571+
572+ func fulfil( _ value: Value ) {
573+ switch self . state {
574+ case . initialised:
575+ self . state = . fulfilled( value)
576+ self . observer? . resume ( returning: value)
577+ case . fulfilled:
578+ preconditionFailure ( " \( Self . self) over fulfilled " )
579+ }
580+ }
581+
582+ var value : Value {
583+ get async {
584+ switch self . state {
585+ case . initialised:
586+ return await withCheckedContinuation { ( continuation: CheckedContinuation < Value , Never > ) in
587+ precondition ( self . observer == nil , " \( Self . self) supports only one observer " )
588+ self . observer = continuation
589+ }
590+ case . fulfilled( let value) :
591+ return value
592+ }
593+ }
594+ }
595+ }
596+
556597@available ( macOS 10 . 15 , iOS 13 . 0 , watchOS 6 . 0 , tvOS 13 . 0 , * )
557598extension Transaction {
558599 fileprivate static func makeWithResultTask(
@@ -561,9 +602,9 @@ extension Transaction {
561602 logger: Logger = Logger ( label: " test " ) ,
562603 connectionDeadline: NIODeadline = . distantFuture,
563604 preferredEventLoop: EventLoop
564- ) -> ( Transaction , _Concurrency . Task < HTTPClientResponse , Error > ) {
565- let transactionPromise = preferredEventLoop . makePromise ( of : Transaction . self )
566- let result = Task {
605+ ) async -> ( Transaction , _Concurrency . Task < HTTPClientResponse , Error > ) {
606+ let transactionPromise = Promise < Transaction > ( )
607+ let task = Task {
567608 try await withCheckedThrowingContinuation { ( continuation: CheckedContinuation < HTTPClientResponse , Error > ) in
568609 let transaction = Transaction (
569610 request: request,
@@ -573,13 +614,13 @@ extension Transaction {
573614 preferredEventLoop: preferredEventLoop,
574615 responseContinuation: continuation
575616 )
576- transactionPromise. succeed ( transaction)
617+ Task {
618+ await transactionPromise. fulfil ( transaction)
619+ }
577620 }
578621 }
579- // the promise can never fail and it is therefore safe to force unwrap
580- let transaction = try ! transactionPromise. futureResult. wait ( )
581622
582- return ( transaction , result )
623+ return ( await transactionPromise . value , task )
583624 }
584625}
585626#endif
0 commit comments