0

I was trying to write my own worker to process big amount of numbers. And decided to make always working Isolate in which all my data would be processed.

class ProjectionWorker {
  
  ...

  Isolate? _isolate;

  ReceivePort? _workerPort;

  Stream? _workerResultStream;

  SendPort? _isolatePort;

  Future<ObjectModel> project(
    ObjectModel model,
    ProjectionData projectionData,
  ) async {
    _workerPort ??= ReceivePort();

    _isolate ??= await Isolate.spawn<SendPort>(
      _isolateScope,
      _workerPort!.sendPort,
      debugName: "flutter_object calculations",
    );

    _workerResultStream ??= _workerPort!.asBroadcastStream();

    _isolatePort ??= await _workerResultStream!.first;

    final Completer<ObjectModel> completer = Completer();

    _workerResultStream!.listen(
      (result) {
        if (result is ObjectModel) completer.complete(result);
      },
    );

    _isolatePort!.send(
      Tuple(
        model,
        projectionData,
      ),
    );

    return completer.future;
  }
}
...

void _isolateScope(SendPort port) async {
  final isolatePort = ReceivePort();

  port.send(isolatePort.sendPort);

  await for (final event in isolatePort) {
    ...

    port.send(result);
  }
}

But when I tried to use it in my custom RenderObject, in paint method:

  Future<void> _projectObject({
    ...
  }) async {
    _projectedObject = await _projectionWorker.project(
      ...
    );

I am receiving this:

Unhandled Exception: Invalid argument(s): Illegal argument in isolate message: (object is a ReceivePort)

And exception throws from this line of code:

...          
_isolatePort!.send(
      Tuple(
        model,
        projectionData,
      ),
    );
...

Am I missing something here?

samir.a.ts
  • 17
  • 6
  • Does this answer your question? [Invalid argument(s): Illegal argument in isolate message: (object is aReceivePort)](https://stackoverflow.com/questions/70764481/invalid-arguments-illegal-argument-in-isolate-message-object-is-areceivepor) – mmcdon20 Jun 14 '22 at 23:30
  • @mmcdon20 unfortunately, no. My function (_isolateScope) is top level and not included in any other class/scope. – samir.a.ts Jun 15 '22 at 07:04
  • Is there any chance that `ObjectModel` or `ProjectionData` have a `ReceivePort` as a property? (either directly or even transitively like a property of a property) – mmcdon20 Jun 15 '22 at 14:44
  • @mmcdon20 no. :( It contains only double, Size, Offset… – samir.a.ts Jun 16 '22 at 10:28
  • Could you provide a [complete minimal example that I could run that would reproduce the error](https://stackoverflow.com/help/minimal-reproducible-example)? (preferably all the necessary code to run it in one file) – mmcdon20 Jun 16 '22 at 15:12
  • @mmcdon20 here: https://gist.github.com/samir-a-ts/e093a69219268aeaa23af30bf14f6422 – samir.a.ts Jun 16 '22 at 19:15
  • I tried running the code in the gist, but it is not producing the error message. – mmcdon20 Jun 16 '22 at 20:03
  • @mmcdon20 that's strange... I would investigate further. – samir.a.ts Jun 17 '22 at 09:30

1 Answers1

0

I just figured it out.

It seems stupid, but it worked out for me, so I hope, it would help somebody else.

In my isolateScope function ReceivePort gets tuple with ObjectModel and ProjectionData

ProjectionData was containing Size property in it, and ObjectModel had Color property.

I cut that both properties out and replaced it with just double or List.

And it just worked out.

It seems, that isolate somehow gets RecievePort by importing flutter/material.dart.

samir.a.ts
  • 17
  • 6