init method

Future<void> init(
  1. MainMessageHandler mainHandler,
  2. IsolateMessageHandler isolateHandler, {
  3. Object? initialMessage = const _NoParameterProvided(),
  4. bool queueMode = false,
  5. MessageHandler? errorHandler,
  6. MessageHandler? exitHandler,
})

The worker initializer.

Provides 4 parameters:

  • MainHandler: Receives and handle the messages coming from the isolate with the message data and the isolate SendPort as parameters, that can be used to send messages back to the isolate or using the send method.

  • IsolateHandler: Receives and handle messages coming from the sender with the message data and the main SendPort as parameters, that can be used to send messages back to the main thread.

  • initialMessage: Can be used to start the isolate sending a initial message

  • queueMode: when enabled, the ports await the last event being handled to read the next one. By default is false.

  • errorHandler: Receives the error events from the isolate. Tt can be non handled errors or errors manually sent using the SendErrorFunction inside the isolate handler.

  • exitHandler: Called when the isolate is being closed.

Important note: Be careful with non handled errors inside the isolate, it automatically closes sending the exit event. To avoid this, you can use try catch on the operations or wraps everything in a runZonedGuarded.

Implementation

Future<void> init(
  MainMessageHandler mainHandler,
  IsolateMessageHandler isolateHandler, {
  Object? initialMessage = const _NoParameterProvided(),
  bool queueMode = false,
  MessageHandler? errorHandler,
  MessageHandler? exitHandler,
}) async {
  assert(isInitialized == false);
  if (isInitialized) return;

  /// The port to communicate with the main thread
  _mainReceivePort = ReceivePort();
  final errorPort = _initializeAndListen(errorHandler);
  final exitPort = _initializeAndListen(exitHandler);

  _isolate = await Isolate.spawn(
    _isolateInitializer,
    _IsolateInitializerParams(
      _mainReceivePort.sendPort,
      errorPort?.sendPort,
      isolateHandler,
      queueMode,
    ),
    onError: errorPort?.sendPort,
    onExit: exitPort?.sendPort,
  );

  /// Listen the main port to handle messages coming from the isolate
  _mainReceivePort.listen((message) async {
    /// The first message received from the isolate will be the isolate port,
    /// the port is saved and the worker is ready to work
    if (message is SendPort) {
      _isolateSendPort = message;
      if (!(initialMessage is _NoParameterProvided)) {
        _isolateSendPort.send(initialMessage);
      }
      _completer.complete();
      return;
    }
    final handlerFuture = mainHandler(message, _isolateSendPort);
    if (queueMode) {
      await handlerFuture;
    }
  }).onDone(() async {
    /// Waits 2 seconds to close the error and exit ports, enabling to receive
    /// the events when the worker is disposed manually.
    await Future.delayed(Duration(seconds: 2));
    errorPort?.close();
    exitPort?.close();
  });

  return await _completer.future;
}