Skip to content
This repository was archived by the owner on Aug 29, 2022. It is now read-only.

Commit 42b8a7a

Browse files
committed
Fixes issue where multiple nested andThen did not track progress (#281)
1 parent 03110da commit 42b8a7a

File tree

1 file changed

+10
-10
lines changed

1 file changed

+10
-10
lines changed

Sources/Task/TaskChain.swift

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,14 @@ struct TaskChain {
3030
/// that first task's `Root`.
3131
@objc(BNRTaskRootProgress)
3232
private class Root: Progress {
33-
/// Key for value of type `Root?` in `Thread.threadDictionary`.
34-
static let threadKey = "_BNRTaskCurrentRoot"
33+
/// Key for value of type `[Root]?` in `Thread.threadDictionary`.
34+
static let threadKey = "_BNRTaskProgressStack"
3535

3636
/// Propogates the current Task chain for explicit composition during
3737
/// `Task.andThen`.
38-
static var active: Root? {
38+
static var activeStack: [Root] {
3939
get {
40-
return Thread.current.threadDictionary[threadKey] as? Root
40+
return Thread.current.threadDictionary[threadKey] as? [Root] ?? []
4141
}
4242
set {
4343
Thread.current.threadDictionary[threadKey] = newValue
@@ -81,7 +81,7 @@ struct TaskChain {
8181
/// Locates or creates the root of a task chain, then generates any
8282
/// progress objects needed to represent `wrapped` in that chain.
8383
init<Wrapped: TaskProtocol>(startingWith wrapped: Wrapped, using customProgress: Progress? = nil, uponCancel cancellation: (() -> Void)? = nil) {
84-
if let root = Root.active {
84+
if let root = Root.activeStack.last {
8585
// We're inside `andThen` — `commitAndThen(with:)` will compose instead.
8686
self.root = root
8787
self.effectiveProgress = customProgress ?? .basicProgress(parent: nil, for: wrapped, uponCancel: cancellation)
@@ -148,27 +148,27 @@ struct TaskChain {
148148
/// progress and attach it to the root. If this next step provides custom
149149
/// progress, give it a 100x slice.
150150
func beginAndThen() {
151-
Root.active = root
151+
Root.activeStack.append(root)
152152
}
153153

154154
/// See `beginAndThen`.
155155
func commitAndThen<Wrapped: TaskProtocol>(with wrapped: Wrapped) {
156-
if let task = wrapped as? Task<Wrapped.Success>, !(task.progress is Root) {
156+
if let task = wrapped as? Task<Wrapped.Success> {
157157
let pendingUnitCount = task.progress.wasGeneratedByTask ? TaskChain.singleUnit : TaskChain.explicitChildUnitCount
158158
root.totalUnitCount += pendingUnitCount - TaskChain.singleUnit
159-
root.adoptChild(task.progress, withPendingUnitCount: pendingUnitCount)
159+
root.monitorChild(task.progress, withPendingUnitCount: pendingUnitCount)
160160
} else {
161161
root.monitorCompletion(of: wrapped, uponCancel: wrapped.cancel, withPendingUnitCount: TaskChain.singleUnit)
162162
}
163-
Root.active = nil
163+
Root.activeStack.removeLast()
164164
}
165165

166166
/// When the `andThen` handler can't be run at all, mark the enqueued unit
167167
/// as complete anyway.
168168
func flushAndThen() {
169169
root.becomeCurrent(withPendingUnitCount: TaskChain.singleUnit)
170170
root.resignCurrent()
171-
Root.active = nil
171+
Root.activeStack.removeLast()
172172
}
173173
}
174174
#endif

0 commit comments

Comments
 (0)