compute<Q, R> function

  1. @experimental
Future<R> compute<Q, R>(
  1. ComputeCallback<Q, R> callback,
  2. Q message, {
  3. String? debugLabel,
})

The dart:io implementation of compute.

Implementation

@experimental
Future<R> compute<Q, R>(
  ComputeCallback<Q, R> callback,
  Q message, {
  String? debugLabel,
}) async {
  debugLabel ??= const bool.fromEnvironment('dart.vm.product')
      ? 'compute'
      : callback.toString();

  final flow = Flow.begin();
  Timeline.startSync('$debugLabel: start', flow: flow);
  final port = RawReceivePort();
  Timeline.finishSync();

  void timeEndAndCleanup() {
    Timeline.startSync('$debugLabel: end', flow: Flow.end(flow.id));
    port.close();
    Timeline.finishSync();
  }

  final completer = Completer<Object?>();
  port.handler = (Object? msg) {
    timeEndAndCleanup();
    completer.complete(msg);
  };

  try {
    await Isolate.spawn<_IsolateConfiguration<Q, R>>(
      _spawn,
      _IsolateConfiguration<Q, R>(
        callback,
        message,
        port.sendPort,
        debugLabel,
        flow.id,
      ),
      onExit: port.sendPort,
      onError: port.sendPort,
      debugName: debugLabel,
    );
  } on Object {
    timeEndAndCleanup();
    rethrow;
  }

  final response = await completer.future;
  if (response == null) {
    throw RemoteError('Isolate exited without result or error.', '');
  }

  assert(response is List<Object?>, 'Unexpected response type: $response');
  response as List<Object?>;

  final type = response.length;
  assert(1 <= type && type <= 3, 'Unexpected response type: $type');

  switch (type) {
    // success; see _buildSuccessResponse
    case 1:
      return response[0] as R;

    // native error; see Isolate.addErrorListener
    case 2:
      await Future<Never>.error(
        RemoteError(
          response[0]! as String,
          response[1]! as String,
        ),
      );

    // caught error; see _buildErrorResponse
    case 3:
    default:
      assert(
        type == 3 && response[2] == null,
        'Unexpected response type',
      );

      await Future<Never>.error(
        response[0]!,
        response[1]! as StackTrace,
      );
  }
}