88import Foundation
99
1010/// A helper for executing asynchronous work serially.
11- public actor TaskQueue < Success> {
12- private var previousTask : Task < Success , Error > ?
11+ public class TaskQueue < Success> {
12+ typealias Block = @Sendable ( ) async -> Void
13+ private var streamContinuation : AsyncStream < Block > . Continuation !
1314
14- public init ( ) { }
15+ public init ( ) {
16+ let stream = AsyncStream < Block > . init { continuation in
17+ streamContinuation = continuation
18+ }
19+
20+ Task {
21+ for await block in stream {
22+ _ = await block ( )
23+ }
24+ }
25+ }
26+
27+ deinit {
28+ streamContinuation. finish ( )
29+ }
1530
1631 /// Serializes asynchronous requests made from an async context
1732 ///
@@ -25,17 +40,31 @@ public actor TaskQueue<Success> {
2540 /// TaskQueue serializes this work so that `doAsync1` is performed before `doAsync2`,
2641 /// which is performed before `doAsync3`.
2742 public func sync( block: @Sendable @escaping ( ) async throws -> Success ) async throws -> Success {
28- let currentTask : Task < Success , Error > = Task { [ previousTask] in
29- _ = await previousTask? . result
30- return try await block ( )
43+ try await withCheckedThrowingContinuation { continuation in
44+ streamContinuation. yield {
45+ do {
46+ let value = try await block ( )
47+ continuation. resume ( returning: value)
48+ } catch {
49+ continuation. resume ( throwing: error)
50+ }
51+ }
3152 }
32- previousTask = currentTask
33- return try await currentTask. value
3453 }
3554
36- public nonisolated func async ( block: @Sendable @escaping ( ) async throws -> Success ) rethrows {
37- Task {
38- try await sync ( block: block)
55+ public func async ( block: @Sendable @escaping ( ) async throws -> Success ) {
56+ streamContinuation. yield {
57+ do {
58+ _ = try await block ( )
59+ } catch {
60+ Self . log. warn ( " Failed to handle async task in TaskQueue< \( Success . self) > with error: \( error) " )
61+ }
3962 }
4063 }
4164}
65+
66+ extension TaskQueue {
67+ public static var log : Logger {
68+ Amplify . Logging. logger ( forNamespace: String ( describing: self ) )
69+ }
70+ }
0 commit comments