Skip to content

Commit 985e917

Browse files
committed
Fixed issue of an exception is raised when a task runs async indepentently of parallel function.
1 parent b411df8 commit 985e917

File tree

3 files changed

+62
-1
lines changed

3 files changed

+62
-1
lines changed

Ax/Ax.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,11 @@ final public class Ax {
4444
public static func parallel(tasks: [TaskClosure], result: @escaping ResultClosure) {
4545
let group = DispatchGroup()
4646
var errorFound: NSError?
47+
var numTaskEntered = 0
4748

4849
for task in tasks {
4950
group.enter()
51+
numTaskEntered += 1
5052

5153
DispatchQueue.global(qos: .background).async {
5254
task({ (error) in
@@ -55,7 +57,10 @@ final public class Ax {
5557
result(error)
5658
}
5759

58-
group.leave()
60+
if numTaskEntered > 0 {
61+
group.leave()
62+
numTaskEntered -= 1
63+
}
5964
})
6065
}
6166
}

AxTests/AxTests.swift

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,21 @@ class AxTests: XCTestCase {
3232
}
3333
}
3434

35+
func runAsync(after seconds: Int, selfCallAfter secondsAfter: Int, closure: @escaping () -> Void) {
36+
let time = DispatchTime.now() + DispatchTimeInterval.seconds(seconds)
37+
let timeAfter = DispatchTime.now() + DispatchTimeInterval.seconds(secondsAfter)
38+
39+
let queue = DispatchQueue(label: "com.ax.runqueue")
40+
41+
queue.asyncAfter(deadline: time) {
42+
closure()
43+
}
44+
45+
queue.asyncAfter(deadline: timeAfter) {
46+
closure()
47+
}
48+
}
49+
3550

3651

3752

@@ -267,6 +282,47 @@ class AxTests: XCTestCase {
267282

268283

269284
// Parallel tests
285+
func testRunningATaskThatSometimesRunsIndependentlyOfParallelFunction() {
286+
287+
let ex = expectation(description: "")
288+
var numCalls = 0
289+
290+
Ax.parallel(tasks: [
291+
292+
{ done in
293+
294+
self.runAsync(after: 1, selfCallAfter: 4, closure: {
295+
numCalls += 1
296+
297+
if numCalls == 2 {
298+
ex.fulfill()
299+
}
300+
301+
done(nil)
302+
})
303+
304+
},
305+
306+
{ done in
307+
308+
self.runAsync(after: 1, closure: {
309+
done(nil)
310+
})
311+
312+
}
313+
314+
]) { (error) in
315+
XCTAssertNil(error)
316+
}
317+
318+
waitForExpectations(timeout: 8) { (error) in
319+
if let error = error {
320+
XCTFail("error: \(error)")
321+
}
322+
}
323+
324+
}
325+
270326
func testRunningThreeTasksInParallelAndEnsureResultCallIsDoneAtFinalState() {
271327
let ex = expectation(description: "Testing tasks that run in parallel and are finished before result closure is called")
272328
var counter = 0

0 commit comments

Comments
 (0)