Skip to content
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

Is a stream created by Stream.multi() always a multi-subscription stream? #56903

Open
sgrekhov opened this issue Oct 16, 2024 · 2 comments
Open
Labels
area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. library-async type-documentation A request to add or improve documentation type-question A question about expected behavior or functionality

Comments

@sgrekhov
Copy link
Contributor

According to Stream.multi documentation

/// Creates a multi-subscription stream.

It's not quite true in the case when a source of MultiStreamController.addStream() is a single-subscription stream. For example:

main() {
  var source = StreamController<int>();
  source.add(1);
  source.add(2);
  source.add(3);
  source.close();

  var stream = Stream<int>.multi((controller) {
    controller.addStream(source.stream).then((_) {
      controller.close();
    });
  });
  listen(stream);
  listen(stream); // Bad state: Stream has already been listened to.
}

void listen(Stream<int> stream) {
  int eventsCounter = 1;
  stream.listen((v) {
    Expect.equals(eventsCounter++, v);
  }, onDone: () {
    Expect.equals(4, eventsCounter);
  });
}

Is this expected? If yes, then, probably, it makes sense to reflect it in the Stream.multi() constructor documentation.

cc @lrhn

@sgrekhov sgrekhov added the type-question A question about expected behavior or functionality label Oct 16, 2024
@dart-github-bot
Copy link
Collaborator

Summary: The issue reports that a stream created by Stream.multi() is not always a multi-subscription stream when the source of MultiStreamController.addStream() is a single-subscription stream, leading to a "Bad state" error when attempting to listen to the stream multiple times. The user suggests updating the Stream.multi() documentation to reflect this behavior.

@dart-github-bot dart-github-bot added area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. triage-automation See https://github.com/dart-lang/ecosystem/tree/main/pkgs/sdk_triage_bot. type-bug Incorrect behavior (everything from a crash to more subtle misbehavior) labels Oct 16, 2024
@lrhn
Copy link
Member

lrhn commented Oct 16, 2024

The documentation should probably be expanded.

The Stream.multi stream can support a wide variety of behaviors, including being listend to multiple times, and the code that provides events can choose to limit what will work.

A "multi-subscription stream" here means a stream which you can call listen on multiple times. The stream itself doesn't prevent that.

If the code that's supposed to provide events to the stream decides to throw during listen, it gets what it asks for. That makes the stream behave like a single-subscription stream. But by that measure, a StreamController(onListen: () { throw "Nah-ah!"; }) is not a single-subscription stream either, but a zero-subscription stream.

More text is probably the way to go.

If nothing else then:

/// Creates a steam which can respond to multiple listeners.
///
/// Each call to [Stream.listen] on the created stream
/// will call [onListen] with a new 
/// [MultiStreamController] which can be used to 
/// send events to that one subscription. 

@lrhn lrhn added library-async type-documentation A request to add or improve documentation and removed type-bug Incorrect behavior (everything from a crash to more subtle misbehavior) triage-automation See https://github.com/dart-lang/ecosystem/tree/main/pkgs/sdk_triage_bot. labels Oct 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. library-async type-documentation A request to add or improve documentation type-question A question about expected behavior or functionality
Projects
None yet
Development

No branches or pull requests

3 participants