Trying my first run converting a complex system to use isolates/workers, i get the exception in the title.
flutter: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'SendPort?'
flutter: #0 openChannel (package:squadron/src/native/channel.dart:103:11)
<asynchronous suspension>
d-markey/squadron_sample#1 Worker.send (package:squadron/src/worker.dart:107:9)
<asynchronous suspension>
d-markey/squadron#3 WorkerTask._runFuture (package:squadron/src/worker_task.dart:148:21)
<asynchronous suspension>
I replicated the thumbnail example as far as I can tell.
Here's my code:
solver_service.dart
import 'dart:async';
import 'package:squadron/squadron.dart';
import '../position_manager_thread.dart';
abstract class SolverService {
FutureOr<Map<String, dynamic>> initRoot(Map<String, dynamic> rootNodeJson);
FutureOr<Map<String, dynamic>> performLayout(
Set<Map<String, dynamic>> nodesReference,
Set<String> createdNodes,
Set<String> removedNodes,
Set<String> adoptedNodes,
Set<String> droppedNodes,
Set<String> changedNodes,
);
static const cmdPerformLayout = 1;
static const cmdInitRoot = 2;
}
class SolverServiceImpl implements SolverService, WorkerService {
final PositionManagerThread positionManager =
PositionManagerThread(notifier: (pos) => print(pos));
@override
FutureOr<Map<String, dynamic>> initRoot(Map<String, dynamic> rootNodeJson) =>
positionManager.initRoot(rootNodeJson).toJson();
@override
FutureOr<Map<String, dynamic>> performLayout(
Set<Map<String, dynamic>> nodesReference,
Set<String> createdNodes,
Set<String> removedNodes,
Set<String> adoptedNodes,
Set<String> droppedNodes,
Set<String> changedNodes,
) async {
return positionManager
.performLayout(
nodesReference,
createdNodes,
removedNodes,
adoptedNodes,
droppedNodes,
changedNodes,
)
.toJson();
}
@override
late final Map<int, CommandHandler> operations = {
SolverService.cmdPerformLayout: (WorkerRequest r) => performLayout(
r.args[0],
r.args[1],
r.args[2],
r.args[3],
r.args[4],
r.args[5],
),
SolverService.cmdInitRoot: (WorkerRequest r) => initRoot(
r.args[0],
),
};
}
solver_worker_activator.dart
:
// stub file, the file used at runtime will depend on the target platform
// * cf "browser\solver_worker_activator.dart" for Web workers (browser platform)
// * cf "vm\solver_worker_activator.dart" for Isolate workers (vm platform)
// of course, if your application does not target both Web and VM platforms,
// you need not define a stub file and can go directly for your target platform
import 'solver_worker_pool.dart' show SolverWorker;
SolverWorker createWorker() =>
throw UnsupportedError('Not supported on this platform');
solver_worker_pool
:
// this is a helper file to expose Squadron workers and worker pools as a SolverService
import 'dart:async';
import 'package:codelessly_flutter/managers/position_manager/multithreading/solver_service.dart';
import 'package:squadron/squadron.dart';
// this is where the stub file comes into action
//
// of course, if your application does not target both Web and VM platforms,
// you need not define a stub file and can go directly for your target platform
import 'solver_worker_activator.dart'
if (dart.library.js) 'package:codelessly_flutter/managers/position_manager/multithreading/browser/solver_worker_activator.dart'
if (dart.library.html) 'package:codelessly_flutter/managers/position_manager/multithreading/browser/solver_worker_activator.dart'
if (dart.library.io) 'package:codelessly_flutter/managers/position_manager/multithreading/vm/solver_worker_activator.dart';
// Implementation of SolverService as a Squadron worker pool
class SolverWorkerPool extends WorkerPool<SolverWorker>
implements SolverService {
SolverWorkerPool(ConcurrencySettings concurrencySettings)
: super(createWorker, concurrencySettings: concurrencySettings);
@override
FutureOr<Map<String, dynamic>> initRoot(Map<String, dynamic> rootNodeJson) =>
execute((w) async => w.initRoot(rootNodeJson));
@override
FutureOr<Map<String, dynamic>> performLayout(
Set<Map<String, dynamic>> nodes,
Set<String> createdNodes,
Set<String> removedNodes,
Set<String> adoptedNodes,
Set<String> droppedNodes,
Set<String> changedNodes,
) =>
execute((w) async => w.performLayout(
nodes,
createdNodes,
removedNodes,
adoptedNodes,
droppedNodes,
changedNodes,
));
}
// Implementation of SolverService as a Squadron worker
class SolverWorker extends Worker implements SolverService {
SolverWorker(dynamic entryPoint, {String? id, List args = const []})
: super(entryPoint, id: id, args: args);
@override
FutureOr<Map<String, dynamic>> initRoot(Map<String, dynamic> rootNodeJson) {
return send(
SolverService.cmdInitRoot,
[
rootNodeJson,
],
);
}
@override
FutureOr<Map<String, dynamic>> performLayout(
Set<Map<String, dynamic>> nodes,
Set<String> createdNodes,
Set<String> removedNodes,
Set<String> adoptedNodes,
Set<String> droppedNodes,
Set<String> changedNodes,
) {
return send(
SolverService.cmdPerformLayout,
[
nodes,
createdNodes,
removedNodes,
adoptedNodes,
droppedNodes,
changedNodes,
],
);
}
}
solver_vm.dart
:
// Isolate implementation (VM patform)
import 'package:squadron/squadron_service.dart';
import '../solver_service.dart';
void start(Map command) => run((startRequest) => SolverServiceImpl(), command);
solver_worker_activator.dart
:
// Creation of the Isolate
import '../solver_worker_pool.dart' show SolverWorker;
import 'solver_worker.dart' as isolate;
SolverWorker createWorker() => SolverWorker(isolate.start);
Usage is quite simple:
// Crashes if maxParallel is set to 1 for some reason. I only want one instance of this worker/isolate at all times through the life cycle of the app
final SolverWorkerPool pool = SolverWorkerPool(
const ConcurrencySettings(minWorkers: 1, maxWorkers: 1, maxParallel: 2));
Future<void> initRoot(RootNode node) async {
final LayoutResult result =
LayoutResult.fromJson(await pool.initRoot(node.toJson()));
I'm not really sure what I'm doing wrong. There's no mention or example that brings up SendPort/ReceiverPort for Squadron.
I get this error for the performLayout() function as well.
I'm running this in a MacOS window. So the isolate only. No javascript