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

Make realAsyncZone run microtasks and timers in the correct zone. #162731

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

lrhn
Copy link
Contributor

@lrhn lrhn commented Feb 5, 2025

Current implementation runs timers and microtask callbacks in the root zone. That assumes that the top-level scheduleMicrotask or Timer constructors have been used, which have so far wrapped the callback with runCallbackGuarded before calling the zone implementation.
That means that doing zone.scheduleMicrotask directly would not ensure that the microtask was run in the correct zone. If a run handler throws, it wouldn't be caught.

This change makes the realAsyncZone do whatever the root zone would do if its ZoneDelegate got called with the intended zone and arguments. That should be consistent with the current behavior, and be compatible with incoming bug-fixes to the platform Zone behavior.

Prepares Flutter for landing https://dart-review.googlesource.com/c/sdk/+/406961
which is currently blocked (so this indirectly fixes dart-lang/sdk#59913).

There are no new tests, the goal is that all existing tests keep running, and that they keep doing so when the Dart CL lands. Currently that CL only breaks one test, the dev/automated_tests/test_smoke_test/fail_test_on_exception_after_test.dart test which threw the error-after-test in the root zone instead of the test zone. This change fixes that.

@flutter-dashboard
Copy link

It looks like this pull request may not have tests. Please make sure to add tests before merging. If you need an exemption, contact "@test-exemption-reviewer" in the #hackers channel in Discord (don't just cc them here, they won't see it!).

If you are not sure if you need tests, consider this rule of thumb: the purpose of a test is to make sure someone doesn't accidentally revert the fix. Ask yourself, is there anything in your PR that you feel it is important we not accidentally revert back to how it was before your fix?

Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing. The test exemption team is a small volunteer group, so all reviewers should feel empowered to ask for tests, without delegating that responsibility entirely to the test exemption group.

@github-actions github-actions bot added a: tests "flutter test", flutter_test, or one of our tests framework flutter/packages/flutter repository. See also f: labels. labels Feb 5, 2025
@@ -1361,7 +1361,7 @@ class AutomatedTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding {
final Zone realAsyncZone = Zone.current.fork(
specification: ZoneSpecification(
scheduleMicrotask: (Zone self, ZoneDelegate parent, Zone zone, void Function() f) {
Zone.root.scheduleMicrotask(f);
_rootDelegate.scheduleMicrotask(zone, f);
Copy link
Contributor Author

@lrhn lrhn Feb 6, 2025

Choose a reason for hiding this comment

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

This could have just done Zone.root.scheduleMicrotask(zone.bindCallbackGuarded(f)), but that's not necessarily the same as what rootDelegate.scheduleMicrotask(zone, f) does.
The bindCallbackGuarded does an extra Zone.registerCalback, and an extra Zone.run on top of what the root zone's scheduleMicrotask would already do.

Using the root zone's delegate ensures that it does exactly the same as if zone had been a direct child of the root zone, just bypassing the intermediate zones in order to get "real" async operations.
It's a "more correct" approach to bypassing the surrounding zone's overloads of microtasks and timers, while still using its intended registerMicrotask and run behaviores.

@stuartmorgan
Copy link
Contributor

test-exempt: unblocks future roll

@lrhn
Copy link
Contributor Author

lrhn commented Feb 6, 2025

Come to think of it, I should be able to add a test that distinguishes the new behavior from the old if I call the Zone.createTimer directly. (Until the Dart CL lands, using the Timer constructor will work the same in both cases.)

Done. Test added.

@flutter-dashboard
Copy link

Golden file changes have been found for this pull request. Click here to view and triage (e.g. because this is an intentional change).

If you are still iterating on this change and are not ready to resolve the images on the Flutter Gold dashboard, consider marking this PR as a draft pull request above. You will still be able to view image results on the dashboard, commenting will be silenced, and the check will not try to resolve itself until marked ready for review.

For more guidance, visit Writing a golden file test for package:flutter.

Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing.

Changes reported for pull request #162731 at sha faa51aa

@flutter-dashboard flutter-dashboard bot added the will affect goldens Changes to golden files label Feb 6, 2025
@lrhn lrhn force-pushed the fix-real-async-zone branch from faa51aa to baea359 Compare February 6, 2025 15:06
@lrhn
Copy link
Contributor Author

lrhn commented Feb 6, 2025

Rebase on current master, hope it fixes golden file tests.

@lrhn lrhn force-pushed the fix-real-async-zone branch 3 times, most recently from ec49c95 to b8d544d Compare February 13, 2025 13:28
@lrhn
Copy link
Contributor Author

lrhn commented Feb 13, 2025

I'm not sure this actually affects goldens (and the triage link is dead).

What is the next step needed to land this? (This question still applies!)

@lrhn lrhn force-pushed the fix-real-async-zone branch 2 times, most recently from 3654429 to e2d301e Compare February 18, 2025 13:57
@justinmc justinmc removed the will affect goldens Changes to golden files label Feb 18, 2025
@justinmc
Copy link
Contributor

Looks like the goldens check is good now? Removing the label.

@lrhn lrhn force-pushed the fix-real-async-zone branch from e2d301e to adb9107 Compare February 19, 2025 12:40
@flutter-dashboard
Copy link

Golden file changes are available for triage from new commit, Click here to view.

For more guidance, visit Writing a golden file test for package:flutter.

Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing.

Changes reported for pull request #162731 at sha adb9107

@flutter-dashboard flutter-dashboard bot added the will affect goldens Changes to golden files label Feb 19, 2025
@lrhn lrhn force-pushed the fix-real-async-zone branch from adb9107 to 33762c7 Compare February 20, 2025 12:47
lrhn added 2 commits February 21, 2025 14:36
Current implementation runs timers and microtask callbacks in the root zone.
That assumes that the top-level `scheduleMicrotask` or `Timer` constructors
have been used, which have so far wrapped the callback with `runCallbackGuarded`
before calling the zone implementation.
That means that doing `zone.scheduleMicrotask` directly would not ensure
that the microtask was run in the correct zone. If a `run` handler throws,
it wouldn't be caught.

This change makes the `realAsyncZone` do whatever the root zone would
do if its `ZoneDelegate` got called with the intended zone and arguments.
That should be consistent with the current behavior, and be compatible
with changes to the platform `Zone` behavior.
@lrhn lrhn force-pushed the fix-real-async-zone branch from 33762c7 to 63849a5 Compare February 21, 2025 13:36
@lrhn
Copy link
Contributor Author

lrhn commented Mar 6, 2025

PTAL. I believe the goldens mark is a false positive.
See #164982 which is the same change without the rebases.

Copy link
Contributor

@justinmc justinmc left a comment

Choose a reason for hiding this comment

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

LGTM from my point of view but I am not familiar with these async zones in the tests. Looks like the goldens check is passing now though.

@lrhn
Copy link
Contributor Author

lrhn commented Mar 19, 2025

Thanks. I'll need someone to land the change too. (If it's someone is familiar with the zones, they can look at it too.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a: tests "flutter test", flutter_test, or one of our tests framework flutter/packages/flutter repository. See also f: labels. will affect goldens Changes to golden files
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Errors are escaping the error zone when thrown from wrapped register* callbacks.
3 participants