12

I'm trying isolates and I'm wondering how could I spawn some of them doing heavy computations that, when the root Isolate ask them for their current computing value they respond it, "on demand".

As far as I know, the only object that can be used as message for the newly created isolates is SendPort, meaning that only the spawned isolate can communicate with the root one. I tried sending a < SendPort,ReceivePort> tuple, but as ReceivePort isn't a SendPort, it's considered as illegal.

In a nutshell:

root <-- isolate good

root <-> isolate how to?

Nico Rodsevich
  • 2,393
  • 2
  • 22
  • 32
  • 1
    https://stackoverflow.com/questions/29247374/what-is-the-best-way-to-track-the-state-of-an-isolate-in-dart/29248794#29248794 is a bit dated but should still work – Günter Zöchbauer Sep 10 '18 at 14:24

2 Answers2

16

With Gunter's comment I made this:

import 'dart:async';
import 'dart:io';
import 'dart:isolate';

Stopwatch stopwatch = new Stopwatch();

main(args) async {
  ReceivePort rPort = new ReceivePort();
  rPort.listen((data) {
    print("<root> $data received");
    if (data is List) {
      String action = data[0];
      if (action == "register") {
        (data[1] as SendPort).send(stopwatch.elapsedMilliseconds);
      }
    }
  });
  stopwatch.start();
  await Isolate.spawn(elIsolate, rPort.sendPort);
  print("isolate spawned in ${stopwatch.elapsedMilliseconds} msecs"); //isolate spawned in 377 msecs
}

void elIsolate(SendPort sPort) {
  ReceivePort rPort = new ReceivePort();
  rPort.listen((data) {
    print("<Isolate> '$data' received"); //<Isolate> '387' received
  });
  sPort.send(["register", rPort.sendPort]);
}

While with Kevin's answer the code simplified to:

import 'dart:async';
import 'dart:io';
import 'dart:isolate';
import 'package:stream_channel/stream_channel.dart';

Stopwatch stopwatch = new Stopwatch();

main(args) async {
  ReceivePort rPort = new ReceivePort();
  IsolateChannel channel = new IsolateChannel.connectReceive(rPort);
  channel.stream.listen((data) {
    print("<root> '$data' received at ${stopwatch.elapsedMilliseconds} msecs"); //<root> 'hello world' received at 1141 msecs
    channel.sink.add(stopwatch.elapsedMilliseconds);
  });
  stopwatch.start();
  await Isolate.spawn(elIsolate, rPort.sendPort);
  print("isolate spawned in ${stopwatch.elapsedMilliseconds} msecs"); //isolate spawned in 1111 msecs
}

void elIsolate(SendPort sPort) {
  IsolateChannel channel = new IsolateChannel.connectSend(sPort);
  channel.stream.listen((data) {
    print("<Isolate> '$data' received");
  });
  channel.sink.add("hello world");
}
Nico Rodsevich
  • 2,393
  • 2
  • 22
  • 32
10

Look at IsolateChannel from the package:stream_channel.

This should provide a LOT of help for what you're trying to do.

Tirth Patel
  • 5,443
  • 3
  • 27
  • 39
Kevin Moore
  • 5,921
  • 2
  • 29
  • 43