Skip to content
This repository has been archived by the owner on Jan 9, 2020. It is now read-only.

fixed state inconstancy when cancelling task #11

Merged
merged 9 commits into from
Feb 9, 2017
8 changes: 6 additions & 2 deletions Sources/Overdrive/Task.swift
Original file line number Diff line number Diff line change
Expand Up @@ -588,8 +588,12 @@ open class Task<T>: TaskBase {
case .initialized:
return isCancelled
case .pending:
guard !isCancelled else {
return true
if isCancelled {
let ready = super.isReady
if ready {
self.state = .ready
}
return ready
}

if super.isReady {
Expand Down
5 changes: 2 additions & 3 deletions Sources/Overdrive/TaskQueue.swift
Original file line number Diff line number Diff line change
Expand Up @@ -195,10 +195,9 @@ open class TaskQueue {
*/
open func add<T>(task: Task<T>) {
if !task.contains(observer: FinishBlockObserver.self) {
unowned let observedTask = task
task.add(observer: FinishBlockObserver { [weak self] in
task.add(observer: FinishBlockObserver { [weak self, unowned task] in
if let queue = self {
queue.delegate?.didFinish(task: observedTask, inQueue: queue)
queue.delegate?.didFinish(task: task, inQueue: queue)
}
})
}
Expand Down
30 changes: 29 additions & 1 deletion Tests/OverdriveTests/DependencyTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -107,5 +107,33 @@ class DependencyTests: TestCase {

waitForExpectations(timeout: 1, handler: nil)
}


func testCancellationOfDependentTask() {
let queue = TaskQueue()
let delay: TimeInterval = 1.0
let delayTask = TestCaseTask(withResult: .value(()), delay: delay)

let equalExpectation = expectation(description: "value is equal to initial value")
let initialValue = 0
var value = initialValue

let modifyTask = InlineTask({
value = 1
})
modifyTask.add(dependency: delayTask)

let checkTask = InlineTask({
XCTAssert(value == initialValue)
equalExpectation.fulfill()
})
checkTask.add(dependency: modifyTask)

queue.add(task: delayTask)
queue.add(task: modifyTask)
queue.add(task: checkTask)

modifyTask.cancel()

waitForExpectations(timeout: delay + 0.5)
}
}
8 changes: 6 additions & 2 deletions Tests/OverdriveTests/TestCase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,21 @@ class TestCaseTask<T>: Task<T> {

/// Test result
let testResult: Result<T>
let delay: TimeInterval


/// Create new instance with specified result
///
/// - Parameter result: Any `Result<T>`
init(withResult result: Result<T>) {
init(withResult result: Result<T>, delay: TimeInterval = 0.0) {
self.delay = delay
self.testResult = result
}

override func run() {
finish(with: testResult)
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double(Int64(self.delay * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC), execute: {
self.finish(with: self.testResult)
})
}
}

Expand Down