performRpc method
- PerformRpcParams params
Initiate an RPC call to a remote participant.
@param params - RPC call parameters.
@returns A promise that resolves with the response payload or rejects with an error.
@throws Error on failure. Details in message.
Implementation
Future<String> performRpc(PerformRpcParams params) async {
final requestId = Uuid().v4();
final completer = Completer<String>();
final maxRoundTripLatency = Duration(seconds: 7);
final minEffectiveTimeout = const Duration(milliseconds: 1000);
try {
final effectiveTimeout = Duration(
milliseconds: (params.responseTimeoutMs.inMilliseconds - maxRoundTripLatency.inMilliseconds)
.clamp(minEffectiveTimeout.inMilliseconds, double.infinity)
.toInt(),
);
await publishRpcRequest(
destinationIdentity: params.destinationIdentity,
requestId: requestId,
method: params.method,
payload: params.payload,
responseTimeout: effectiveTimeout,
version: kRpcVesion,
);
final ackTimer = Timer(maxRoundTripLatency, () {
completer.completeError(RpcError.builtIn(RpcError.connectionTimeout));
_pendingResponses.remove(requestId);
});
_pendingAcks[requestId] = (id) {
ackTimer.cancel();
};
final responseTimer = Timer(params.responseTimeoutMs, () {
completer.completeError(RpcError.builtIn(RpcError.responseTimeout));
_pendingResponses.remove(requestId);
});
_pendingResponses[requestId] = (String? response, RpcError? error) {
responseTimer.cancel();
if (error != null) {
completer.completeError(error);
} else {
completer.complete(response!);
}
ackTimer.cancel();
_pendingAcks.remove(requestId);
};
} catch (e) {
if (!completer.isCompleted) {
completer.completeError(e);
}
}
return completer.future;
}