-
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
StreamQueue throws 'Bad state: No elements' unexpectedly. #50217
Comments
It looks |
I haven't reproduce it with SDK 2.17 or earlier, but I suspect that it is related with the following change. Haven't |
Do you have multiple loops while (await queries.hasNext) {
await queries.next;
} going on concurrently on the same |
Yes, it does. |
Then I think this is expected behaviour. The code you have written is inherently racy. There is no atomicity guarantees: between /cc @lrhn to confirm |
I can't believe so, because the API reference doesn't sa so, and there is no |
For your information, in case that the queue length = 6 * n + α (n > 1 and 6 > α > 0), it works well. |
What @mraleph says. There being no It's not even a race, the stream queue is race-safe. It's also very much single-threaded by design. The requests of a There is no way around this, that's how the stream queue is designed, the requests are handled as a queue (that's where the Instead of having six independent listeners on the queue, you should have one listener which multiplexes the events to the six workers. We could add a do {
var list = await streamQueue.take(1);
if (list.isEmpty) return;
var event = list[0];
...
} |
do {
var list = await streamQueue.take(1);
if (list.isEmpty) return;
var event = list[0];
...
} Yes, current workaround does so. |
As I said, in case that the queue length = 6 * n + α (n > 1 and 6 > α > 0), it works well. |
For your information, when use |
The reason it works for more than six events is probably that your event handling is asynchronous and slower then the event generation. The stream/request queue initially looks like:
Then you emit an element to the stream, which makes it:
Then the requests start completing. Every time they, do, they add a
Then the first
If another five events come in before that async computation is done, then you end up with an empty queue again.
Then one computation completes, adds
If the next stream event arrives before any other computation completes, then everything will work fine, the event is read, and the stream and queue go back to sleeping. So, if your event generation is snappy, and the event handling is slow, then your strategy will (almost always) work, because there is only one request in the queue at a time. Except at the beginning, where they all start at the same time. |
Yes, I think so. |
Dart SDK version: 2.18.2 (stable) (Unknown timestamp) on "linux_x64"
AOT compiled.
There are 6
sendReceve
invocations, and 3 of them throws "Bad state: No elements" at invocationawait queries.next
.There is no
await
betweenawait queries.hasNext
andawait queries.next
.VM mode crashes for another or same reason of #50082.
The text was updated successfully, but these errors were encountered: