Issue #549

Use Semaphore

public class Sequence: Task {
    public func run(workflow: Workflow, completion: @escaping TaskCompletion) {
        let semaphore = DispatchSemaphore(value: 0)
        runFirst(tasks: tasks, workflow: workflow, completion: { result in
            completion(result)
            semaphore.signal()
        })

        semaphore.wait()
    }
}

public class Concurrent: Task {
    public func run(workflow: Workflow, completion: @escaping (Result<(), Error>) -> Void) {
        var runTaskCount = 0
        let taskCount = tasks.count
        let semaphore = DispatchSemaphore(value: 0)

        tasks.forEach { task in
            task.run(workflow: workflow, completion: { _ in
                self.serialQueue.async {
                    runTaskCount += 1
                    if runTaskCount == taskCount {
                        completion(.success(()))
                        semaphore.signal()
                    }
                }
            })
        }

        semaphore.wait()
    }
}

Read more