Open pinyin opened 3 years ago
There is no API for checking whether an event may currently be added, synchronous or asynchronous. In almost all cases, the answer is "yes" because the event will either be delayed or buffered if it cannot currently be delieverd. There are two exceptions:
The stream has been closed. In the case, you can use the isClosed getter to check for it.
The stream is a synchronous broadcast stream which is currently delivering another event to multiple listeners. That controller cannot buffer the event before delivering it because buffering happens in the subscription objects, and it can't delay the event because it's supposed to be synchronous. It also can't deliver the event immediately because that would risk delivering events out of order, something which must not happen according to the stream contract.
That's a very precise exception, and it requires you to be using a synchronous controller. Synchronous controllers are sharp tools, they're easy to use incorrectly, and if you do, you get unexpected errors. I recommend just making the controller non-synchronous, that's always a correct and safe behavior for a stream. Streams do not promise synchronous delivery, and synchronous controllers exist only for behind-the-scenes optimizations, not as a source of synchronous events. They're simply not built for that.
Thanks for your reply.
There is no API for checking whether an event may currently be added, synchronous or asynchronous.
I understand that a StreamController does not guarantee whether an event is delivered to a subscription. But even though it doesn't give such guarantee, some of its subclasses (e.g. BroadcastStreamController) does throw an exception in add
when _mayAddEvent
is internally false. Checking isClosed
does not cover the case when an addStream
call is not finished.
So even when I don't care whether an event would be added, calling add
may still throw in a BroadcastStreamController
, which may be making the behavior quite inconsistence across asynchronous StreamController implementations.
Changing the implementation is not an option, since in 3rd-part libraries like rxdart, a BroadcastStreamController is simply used everywhere, which makes every fire-and-forget add
intention quite tedious.
Ah, yes, I forgot the "while adding stream" exception. I plan to remove that exception, but hasn't managed to complete the change yet.
Short answer: Adding a member to StreamController
is a breaking change, so we won't do it unless the benefit outweighs the cost. Keeping track of how you're using the controller is the job of the owner, the controller simply reports violations by throwing.
OK, removing the exception seems to be a good solution.
Thanks for your great work. Dart is my favorite language now, hoping it would be even better.
In my understanding,
Stream._mayAddEvent
is not exposed in a synchronous interface, which makes it quite inconvenient to prevent_addEventError
when callingStream#add
.Ideally, calling
add
on aStream
should not require the caller function to be an async function: