Skip to content

Update long running isolate sample to use run() #165

Open
@MaryaBelanger

Description

@MaryaBelanger

I have this example from @lrhn that could be used to update long_running_isolate.dart

In Lasse's words: This is a fairly primitive version of remote-running a stream function, it doesn't forward pause/resume/cancel calls on the subscription, and it stops on the first error. It does show how to send multiple events back from the other isolate.

import "dart:isolate";

Stream<T> runStream<T>(Stream<T> Function() remoteStream) =>
    Stream.multi((controller) async {
      // New port for event messages.
      var port = RawReceivePort();
      port.handler = (message) {
        var list = message as List;
        if (list.length == 1) {
          controller.add(list[0] as T);
        } else {
          controller.addError(list[1] as Object, list[2] as StackTrace);
        }
      };
      // Run in other isolate, receive stream events on `port`.
      try {
        await Isolate.run(_remoteStream(remoteStream, port.sendPort));
        // Returns when stream done.
      } catch (e, s) {
        controller.addError(e, s);
      } finally {
        port.close();
        controller.close();
      }
    });

// Creates an argument to `Isolate.run` from a `Stream Function()` and a port.
Future<void> Function() _remoteStream(
    Stream Function() createStream, SendPort port) {
  Future<void> runStreamSendEvents() async {
    try {
      await for (var event in createStream()) {
        // Send events on port.
        port.send([event]);
      }
    } catch (e, s) {
      // Send events on port.
      port.send([e, s]);
    }
  }

  return runStreamSendEvents;
}

// Example use:

void main() async {
  await for (var v in runStream(() => someInts(5))) {
    print(v);
  }
}

Stream<int> someInts(int n) async* {
  for (var i = 0; i < n; i++) {
    yield i;
  }
}

There's value in keeping the sample as-is, using primitives, rather than replacing it. Using primitives without run is still a use case, even if this particular solution can be modified with run, it's still good to maintain a large example of primitive usage. So maybe another sample can be created, that just shows the same solution written with run.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions