-
Notifications
You must be signed in to change notification settings - Fork 49
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
_StreamQueue._cancel() causes Stream StateError #72
Comments
CC @lrhn |
For the moment, I'm going to just wrap the call in a try/catch/finally. Again, this is happening when the process is closing down. |
The stream needs to be listened to once in order to forward the return value from Here is one test that fails if we don't listen first: async/test/stream_queue_test.dart Lines 484 to 490 in 30e9ccc
I think in practice very few Changing this behavior would be breaking. Given the current documentation it might be preferable to change it, but I'm not sure if it's worth the breaking change. I think, though, in general we don't really want to support the use case of creating multiple |
Yeah, my approach described above works for now, but it's definitely a hack. An alternative that may make sense is to change the implementation of I talked to @mit-mit about having someone from Dart lang team look at this. |
So the problem is that you have two different clients trying to use I guess the test code could be changed to not cancel the stream unless it has actually been used (it would then have to record that somewhere). |
Yeah, lazy initialization is not very pretty in dart, but I've got a patch to do exactly this. But I'm still confused by why you think we would be 'lucky' if someone used the STDIN stream only once. To be honest, I'm actually confused by the semantics of having a stream be only listened to once period. To me, that's like saying you can only only iterate a list once. The current API requires I know way too much about the implementation of every other thing in not only my program, but also all of it's dependencies - possibly even the Dart standard library. Developers should be able to use a Stream and not worry about StateErrors that that stem from behavior outside of their own application code, especially since these sort of Effects are not transparent in the type system. The following should probably be cross posted in an issue on dart-lang/sdk: Some of this would be easier if you could ask a Stream whether it's been listened to or not, but with the current API, I need to wrap a call to A more sensible API would be to have I don't really want to create multiple
So, in my mind that means return the future from cancelling the current subscription if one exists, or a Future otherwise. So something roughly like this: Future _cancel() {
if (_isDone) return null;
var future = _subscription != null ? Future.value(null) : _subscription.cancel();
_close();
return future;
} |
I think that would be the right approach too - but I also don't think it's worth the breaking change. |
@natebosch has there been development or alternative ideas on this issue? |
@ened - I'll tag with "next breaking release" so that if we have some other compelling reason to bump the version here we can fix this along with it - as I mentioned earlier I don't think it's worth a major version release for just this change. The recommendation is still to avoid wrapping a single subscriber stream in a |
For the record, the behavior is intentional. We want the stream to be cleaned up when you close the stream queue. |
No change planned. |
In the process of building an incremental test runner for Flutter, I've come across an interesting bug. I use the
AnsiTerminal terminal
defined as a global getter inside the flutter_tools package. Being anAnsiTerminal
it is bound tostdin
.We use the test running facilities provided in dart-lang/test via package:test_core/src/executable.dart. Their
io
libary binds tostdin
lazily through aStreamQueue
(after a transform that splits the lines). We never cause the binding to happen, and things work well during the invocation. But when we nicely close out all of our resources when we go to shutdown the process, it blows up with a StateError do to these two lines in _StreamQueue._cancel()I'm trying to understand the rationale behind this, and maybe what strategy I can use to work around it. Removing those lines seems to have no affect on this narrow case, but I'm sure that this has some meaningful semantics in other context.
The text was updated successfully, but these errors were encountered: