Skip to content

Conversation

@isoos
Copy link
Collaborator

@isoos isoos commented Nov 18, 2025

No description provided.

@isoos isoos requested a review from jonasfj November 18, 2025 09:06
@isoos
Copy link
Collaborator Author

isoos commented Nov 18, 2025

This breaks 6 of 8 tests without the timer triggered delay from #9069. If the run* zone overrides were removed, all the 8 tests fails.

However, it fixes the fragile task_test.dart in #9069, though the wall-clock time rises to ~90-100 seconds to run all 8 tests. It turns out that the tests will create roughly ~171k timer instances, of which ~57k will be clock-controlled timers (33%).

Maybe we could do smarter re-entry detection and possibly separate the control zone of the ClockControl from the execution zone, I'm not sure if it is worth the effort to look into this further.

Comment on lines 67 to 78
final current = StackTrace.current.toString();
if (current.contains('ClockController._createTimer') ||
current.contains('ClockController._triggerPendingTimers') ||
current.contains('ClockController._cancelPendingTimer')) {
return parent.createTimer(zone, duration, f);
}
final clockCtrl = zone[_clockCtrlKey];
if (clockCtrl is ClockController) {
return clockCtrl._createTimer(duration, f);
} else {
return parent.createTimer(zone, duration, f);
}
Copy link
Member

Choose a reason for hiding this comment

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

I think this is remarkably brave, and what does this do?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The first few lines detects if the timer is created inside the ClockControl's internal timer-related methods or outside of it, and if inside, we return the default timers.

I think this part could be much smarter, e.g. ClockControl should create these timers outside of the current zone, maybe in the root zone.

The next part is a sanity check: if we are inside the clock-controlled zone (which we always should be as we fork it inside of it), and creates a timer that is both an internal object we use to track and elapse, and an implementation of Timer which can be returned (so that the caller may cancel it, also removing it from the tracking).

@isoos
Copy link
Collaborator Author

isoos commented Nov 18, 2025

Note: the new version takes about 1 minute to run the task_test.dart with the delayed datastore ops from #9069.

@isoos
Copy link
Collaborator Author

isoos commented Nov 19, 2025

The periodic timer implementation may be a bit sub-optimal, but seems to work in both at HEAD and in #9069. I think this could be an acceptable way of writing time-control tests, but I would also refactor/expose the loop internals and make them independently testable.

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

Successfully merging this pull request may close these issues.

2 participants