Skip to content

Cancelling Async Generator Hangs Indefinitely #59793

@tustvold

Description

@tustvold

Problem

Given the following stream

Stream<String> foo() {
  final controller = StreamController<String>();
  controller.onListen = () => controller.add("FOO");
  controller.onCancel = () => print("Shutting down");
  controller.onPause = () => print("Pause");
  controller.onResume = () => print("Resume");
  return controller.stream;
}

If we then wrap this in

Stream<String> watch() async* {
  final response = foo();
  final mapped = response.map((response) {
    return response.toUpperCase();
  });
  yield* mapped;
}

Everything works correctly

Future main() async {
  final stream = watch().listen((x) => print(x));
  
  await Future.delayed(Duration(seconds: 1));
  
  await stream.cancel();
  print("finished");
}

Prints as expected

FOO
Shutting down
finished

If, however, we change watch to be

Stream<String> watch() async* {
  final response = foo();
  await for (var response in response) {
    yield response.toUpperCase();
  }
}

Cancellation hangs indefinitely.

The specification has the following to say on the topic.

The stream associated with an asynchronous generator could be canceled
by any code with a reference to that stream at any point
where the generator was passivated.
Such a cancellation constitutes an irretrievable error for the generator.
At this point, the only plausible action for the generator is
to clean up after itself via its \FINALLY{} clauses.%

I'm not entirely sure what passivated means, but I think hanging indefinitely is at least not an obvious behaviour if it is intentional.

Platform

I have tested this on Linux (flutter), Android (flutter) and DartPad and the behaviour seems to be consistent

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-core-librarySDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries.closed-as-intendedClosed as the reported issue is expected behaviortriage-automationSee https://github.com/dart-lang/ecosystem/tree/main/pkgs/sdk_triage_bot.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions