isolate<Id, Value, T> static method
Future<_Communicator<Id, Value> >
isolate<Id, Value, T>(
- ValueSetter<
BackendArgument< create,T> > - String isolateId, {
- required IsolatorData<
T> isolatorData, - ErrorHandler? errorHandler,
- bool isMessageBus = false,
Implementation
static Future<_Communicator<Id, Value>> isolate<Id, Value, T>(
ValueSetter<BackendArgument<T>> create,
String isolateId, {
required IsolatorData<T> isolatorData,
ErrorHandler? errorHandler,
bool isMessageBus = false,
}) async {
/// In flow, when the first Backend was not created and we try to create
/// the second or N-th Backend in [Future.wait]
if (_needToWaitMessageBusCreation(isolateId)) {
await _waiter(isolateId);
}
/// create message bus on first isolator init
if (!_isMessageBusCreated) {
_isMessageBusCreated = true;
await _createMessageBus();
}
final Completer<_Communicator<Id, Value>> completer = Completer();
final ReceivePort receivePort = ReceivePort();
final SendPort sendPort = receivePort.sendPort;
final Stream<dynamic> receiveBroadcast = receivePort.asBroadcastStream();
final StreamSubscription<dynamic> subscription = receiveBroadcast.listen((dynamic message) {
if (message is Packet2<SendPort, SendPort?>) {
if (message.value2 != null) {
_messageBusFrontend!.addIsolateSendPort(Packet2(isolateId, message.value2!));
}
completer.complete(
_Communicator<Id, Value>(
Stream.castFrom<dynamic, _Message<Id, Value>>(receiveBroadcast),
_Sender<Id, Value>(message.value),
),
);
}
});
_isolates[isolateId]?.kill();
_isolates[isolateId] = await Isolate.spawn(
create,
BackendArgument<T>(
sendPort,
data: isolatorData.data,
config: isolatorData.config.toJson(),
messageBusSendPort: isMessageBus ? null : _messageBusBackendSendPort,
),
debugName: isolateId,
errorsAreFatal: false,
);
final Isolate isolate = _isolates[isolateId]!;
final ReceivePort errorReceivePort = ReceivePort();
/// messageAndStackTrace is a List<String> -> [message, stackStrace]
errorReceivePort.listen((dynamic messageAndStackTrace) async {
if (IsolatorConfig._instance.logEvents) {
print('[ERROR] - [$isolateId] !!! The error was thrown in backend and got in Frontend');
}
if (errorHandler != null) {
/// Use only error
await errorHandler(messageAndStackTrace[0]);
}
throw messageAndStackTrace as Object;
});
isolate.addErrorListener(errorReceivePort.sendPort);
final _Communicator<Id, Value> communicator = await completer.future;
await subscription.cancel();
return communicator;
}