Skip to content

Schedule tasks which are futures to completion#112269

Merged
auto-submit[bot] merged 4 commits intoflutter:masterfrom
jiahaog:fix-taskcallback
Oct 6, 2022
Merged

Schedule tasks which are futures to completion#112269
auto-submit[bot] merged 4 commits intoflutter:masterfrom
jiahaog:fix-taskcallback

Conversation

@jiahaog
Copy link
Member

@jiahaog jiahaog commented Sep 23, 2022

Today, scheduleTask to does not execute the scheduled task to completion, when the task is a future. If we are providing a Future<int> Function() to scheduleTask, the current implementation of scheduleTask returns a future when this task starts, but not when it completes. To actually run the task to completion, the callsite needs to look something like the following, which is kind of awkward:

void foo() async {
  Future<int> Function() task = () async => 1;

  // Awkward?
  await await binding.scheduleTask(task, ...);
}

I stumbled across this when using the API above but with a single await, and I was quite confused why the unawaited_futures lint was triggering which led me to looking deeper at the issue.

It would be desirable for task to be scheduled to completion, even when task is a function that returns a future for a simpler API. We can already opt-into this behavior "for free" when the future is handed to completer. The signature of Completer.complete is:

void complete(
  [FutureOr<T>? value]
)

From the docs (emphasis mine):

[case 1] Completes future with the supplied values.
...
[case 2] If the value is itself a future, the completer will wait for that future to complete, and complete with the same result, whether it is a success or an error.

Today, we're hitting the first case, but with the correct type annotations in this PR, we could get the second.

I also tested this change in an internal presubmit (tap/476354531), and it passes tests so it doesn't look like a breaking change.

Pre-launch Checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I read the Tree Hygiene wiki page, which explains my responsibilities.
  • I read and followed the Flutter Style Guide, including Features we expect every widget to implement.
  • I signed the CLA.
  • I listed at least one issue that this PR fixes in the description above.
  • I updated/added relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making, or this PR is test-exempt.
  • All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel on Discord.

@flutter-dashboard flutter-dashboard bot added the framework flutter/packages/flutter repository. See also f: labels. label Sep 23, 2022
@jiahaog jiahaog changed the title Fix type of TaskCallback Schedule tasks which are futures to completion Sep 26, 2022
@jiahaog jiahaog marked this pull request as ready for review September 26, 2022 08:52
@goderbauer goderbauer requested a review from chunhtai September 27, 2022 22:11
@jiahaog
Copy link
Member Author

jiahaog commented Oct 4, 2022

Friendly ping - @chunhtai can you please take a look 🙂

Copy link
Contributor

@chunhtai chunhtai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, left a documentation nit

/// The type argument `T` is the task's return value. Consider `void` if the
/// task does not return a value.
typedef TaskCallback<T> = T Function();
typedef TaskCallback<T> = FutureOr<T> Function();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add some documentation in scheduleTask method to mention the behavior.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Looking at scheduleTask, the doc comment mentions:

Schedules the given task with the given priority and returns a Future that completes to the task's eventual return value.

This seems to already imply that the task will complete (irregardless of whether the task is async or not). In that case do you think we should still need to update it?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

eventual return value part is a bit vague. maybe add phrase to describe the behavior more clearly.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, would you like to take a look again?

Copy link
Contributor

@chunhtai chunhtai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

autosubmit Merge PR when tree becomes green via auto submit App framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants