Reputation: 2665
In playing with Dart, particularly the dart:io
library, I've found myself doing weird things with Streams to allow multiple listeners.
For example, I want to emulate the handler-stack pattern found in a number of Node libraries (like Connect & Express). To do so, I need to be able to set up multiple listeners on the request (and response), which means producing a broadcast stream from the request.
This cannot be the only thing I pass around becuase it does not maintain the properties of the request object (such as the response).
handleRequest (HttpRequest request) {
var stream = request.asBroadcastStream();
// pass stream *and* request to the handlers
}
An example handler, showing the problem, might look like this:
log (HttpRequest request, Stream stream) {
DateTime start = new DateTime.now();
stream.listen(null,
onDone: () {
DateTime finish = new DateTime.now();
print("${request.method} ${request.uri} -> ${request.response.statusCode} ${finish.difference(start).inMilliseconds}ms");
});
}
What's the idiomatic way of doing this kind of thing? I don't want to force Dart to conform to my JavaScriptish way.
Upvotes: 4
Views: 311
Reputation: 8128
The asBroadcastStream()
method is one of the most abused methods of Streams. I have written an article on Streams, and I hope it will be published soon. In short: the lifetime of a single-subscription Stream is defined by its subscription, and asBroadcastStream()
destroys the lifetime management of a Stream. It's a source for resource leaks.
If you want to inform other parts of your program of messages you get from a single-subscription stream it is probably the best to create a new BroadcastStream (independent from the single-subscription stream) where you post messages when they arrive from the single-subscription stream. If these need more information you should send it this way.
In other words: create a new StreamController.broadcast
and share this one with interested parties. If you want, you can also extend Stream and provide more information this way. Keep the single-subscription stream for yourself and publish interesting information in the shared broadcast stream.
Single-subscription streams are designed to be consumed by one entity.
Edit: the article has been published here.
Upvotes: 2