samples icon indicating copy to clipboard operation
samples copied to clipboard

Update long running isolate sample to use `run()`

Open MaryaBelanger opened this issue 2 years ago • 0 comments
trafficstars

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.

MaryaBelanger avatar Jan 31 '23 19:01 MaryaBelanger