use of io.libp2p.core.Stream in project teku by ConsenSys.
the class RpcHandler method sendRequest.
public SafeFuture<RpcStreamController<TOutgoingHandler>> sendRequest(Connection connection, TRequest request, TRespHandler responseHandler) {
final Bytes initialPayload;
try {
initialPayload = rpcMethod.encodeRequest(request);
} catch (Exception e) {
return SafeFuture.failedFuture(e);
}
Interruptor closeInterruptor = SafeFuture.createInterruptor(connection.closeFuture(), PeerDisconnectedException::new);
Interruptor timeoutInterruptor = SafeFuture.createInterruptor(asyncRunner.getDelayedFuture(TIMEOUT), () -> new StreamTimeoutException("Timed out waiting to initialize stream for protocol(s): " + String.join(",", rpcMethod.getIds())));
return SafeFuture.notInterrupted(closeInterruptor).thenApply(__ -> connection.muxerSession().createStream(this)).thenWaitFor(StreamPromise::getStream).orInterrupt(closeInterruptor, timeoutInterruptor).thenCompose(streamPromise -> {
final SafeFuture<String> protocolIdFuture = SafeFuture.of(streamPromise.getStream().thenCompose(Stream::getProtocol));
// waiting for controller, writing initial payload or interrupt
return SafeFuture.of(streamPromise.getController()).<String, RpcStreamController<TOutgoingHandler>>thenCombine(protocolIdFuture, (controller, protocolId) -> {
final TOutgoingHandler handler = rpcMethod.createOutgoingRequestHandler(protocolId, request, responseHandler);
controller.setOutgoingRequestHandler(handler);
return controller;
}).orInterrupt(closeInterruptor, timeoutInterruptor).thenWaitFor(controller -> controller.getRpcStream().writeBytes(initialPayload)).orInterrupt(closeInterruptor, timeoutInterruptor).whenException(err -> closeStreamAbruptly(streamPromise.getStream().join()));
}).catchAndRethrow(err -> {
if (ExceptionUtil.getCause(err, ConnectionClosedException.class).isPresent()) {
throw new PeerDisconnectedException(err);
}
});
}
Aggregations