Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cancellation trumps error in -[BFTask taskForCompletionOfAllTasks:] #87

Closed
jhollida24 opened this issue Apr 1, 2015 · 4 comments
Closed

Comments

@jhollida24
Copy link

I have a scenario where I have many, many network requests to make. I would like to provide a BFTask for the completion of all of them.

I want to be able to cancel them if necessary. Also, if any of them individually fail, I would like to abort the ones not yet dispatched. They are all scheduled on a BFExecutor built from an NSOperationQueue.

Each task begins with a check on a shared cancellationToken to see if they should proceed. If the request fails, it returns its error and sets the cancellationToken to true. The remaining tasks in the queue then check the cancellationToken and dutifully return -[BFTask cancelledTask] when they get their turn.

The problem is that the continuation block for -[BFTask taskForCompletionOfAllTasks:] gives cancellations precedent over errors. So, the task for the completion of all of them returns a cancelled task instead of an error. There's an important distinction there. I want to message errors in my user experience, but not cancellations.

I suspect it's intentional, but I don't know why. Is my use of the same cancellation token for canceling and errors discouraged? Or is this something that you could possibly change (to give errors precent over cancellations)?

@josephearl
Copy link

@nlutsenko-fb @grantland

The problem is that the continuation block for -[BFTask taskForCompletionOfAllTasks:] gives cancellations precedent over errors.

Is this the desired behaviour for taskForCompletionOfAllTasks / whenAll?

@grantland
Copy link
Member

This seems like a bug in the iOS implementation. The .NET docs state that it goes Error > Cancelled > Success (https://msdn.microsoft.com/en-us/library/hh194766(v=vs.110).aspx) and our Android implementation follows this as well:

Task<Void> taskA = Task.forError(new RuntimeException("This task failed."));
Task<Void> taskB = Task.forResult(null);
Task<Void> taskC = Task.cancelled();
Task.whenAll(Arrays.asList(taskA, taskB, taskC)).continueWithTask(new Continuation<Void, Task<Void>>() {
  @Override
  public Task<Void> then(Task<Void> task) throws Exception {
    Log.d("test", "isFaulted=" + task.isFaulted() + " isCancelled=" + task.isCancelled() + " isComplete=" + task.isCompleted());
    return null;
  }
}).waitForCompletion();
04-15 13:50:08.109    1955-1970/? D/test﹕ isFaulted=true isCancelled=false isComplete=true

@grantland grantland assigned ghost Apr 15, 2015
ghost pushed a commit that referenced this issue Apr 15, 2015
@ghost
Copy link

ghost commented Apr 15, 2015

Fixed by #93

@ghost ghost closed this as completed Apr 15, 2015
@jhollida24
Copy link
Author

Thanks guys!

@ghost ghost removed their assignment May 7, 2015
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants