-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Wrong behavior of yield
when associated stream is cancelled
#49451
Comments
@lrhn, WDYT? |
Sounds plausible. This was never correctly implemented originally, and we had some improvements recently, but apparently it didn't fix everything. (We have a test for this already: https://github.com/dart-lang/sdk/blob/main/tests/language/async_star/cancel_while_paused_at_yield_test.dart.) The VM fails two tests in that directory:
(The "Pass" result tests seems like it's still marked as expected failing?) |
Reassigning to @alexmarkov who is working on async/async* atm. |
Please note that in the example above the following line seems important // Give the stream some time to be actually paused
await Future.delayed(Duration(milliseconds: 100)); If I remove this line, then tests passes on my machine. I tried it on DartPad the results there are opposite. Test passes as it is and fails without this line. I have no explanation why it is so. Test doesn't look racy for me |
The await is important because it's the difference between the subscription being paused and cancelled during the event delivery, which means it can ignore the pause and be recognized as cancelled on return, and the subscription merely being paused when the event delivery returns, and then later being cancelled before it resumes. That is: The When the subscription is then cancelled, after control has returned to the paused |
https://dart-review.googlesource.com/c/sdk/+/251562 fixes this bug in the VM. However, it breaks @lrhn Could you confirm that |
@alexmarkov I'm rewriting these tests now. Please see dart-lang/co19#1370 |
@lrhn is there any difference if function, listening a stream, associated with Stream<int> generator() async* { ... }
main() {
Stream<int> s = generator();
late StreamSubscription<int> ss;
ss = s.listen((int i) {
...
}); In the case above |
The generator function waits at the first It means that whichever code called So the (BTW, The |
According to the yield specification
In fact, if stream is paused then function is blocked at
yield
statement (as specified above) but if the stream is cancelled, then ityield
doesn't acts as areturn;
but performs one more iteration and only the nextyield
acts as areturn;
statement.Example
As you can see one more excessive expensive computation was performed after cancelling of the stream
Tested on
Dart SDK version: 2.18.0-271.0.dev (dev) (Sat Jul 9 12:06:18 2022 -0700) on "windows_x64"
The text was updated successfully, but these errors were encountered: