request<R> method

Future<R> request<R>(
  1. String command, {
  2. Map<String, Object?>? data,
  3. Duration timeout = const Duration(seconds: 3),
})

Send a typed request and await the response with timeout protection.

Perfect for request/reply patterns with background isolates. Creates a dedicated reply port, sends the request, and waits for exactly one response. Handles timeouts and error payloads automatically.

Parameters:

  • command: The command string for the worker to process
  • data: Optional data payload to include with the request
  • timeout: Maximum time to wait for a response (default: 3 seconds)

Background Processing Example:

// Main isolate - send heavy computation to worker
final result = await workerPort.request<ComputationResult>(
  'compute_statistics',
  data: {
    'dataset': millionRecords,
    'algorithm': 'advanced_analysis'
  },
  timeout: Duration(minutes: 10),
);

print('Computation complete: ${result.summary}');

Image Processing Example:

// Offload image processing to background isolate
final processedImage = await imageWorkerPort.request<Uint8List>(
  'apply_filters',
  data: {
    'image_data': originalImageBytes,
    'filters': ['blur', 'sharpen', 'contrast'],
  },
);

Error Handling:

try {
  final result = await workerPort.request<String>('process');
} on TimeoutException {
  print('Worker took too long to respond');
} on StateError catch (e) {
  print('Worker returned error: $e');
}

Implementation

Future<R> request<R>(
  String command, {
  Map<String, Object?>? data,
  Duration timeout = const Duration(seconds: 3),
}) async {
  final completer = Completer<Object?>();
  final reply = RawReceivePort();

  reply.handler = (Object? msg) {
    if (completer.isCompleted) return;
    completer.complete(msg);
  };

  sendCmd(command, data: {...?data, 'reply': reply.sendPort});

  try {
    final obj = await completer.future.timeout(
      timeout,
      onTimeout: () {
        throw TimeoutException(
          'request("$command") timed out after $timeout',
        );
      },
    );

    if (obj is Map && obj['error'] != null) {
      throw StateError('request("$command") failed: ${obj['error']}');
    }

    try {
      return obj as R;
    } on TypeError {
      throw StateError(
        'request("$command") returned incompatible type: ${obj.runtimeType} expected: $R',
      );
    }
  } finally {
    reply.close();
  }
}