Search in sources :

Example 1 with StreamPromise

use of io.libp2p.core.StreamPromise 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);
        }
    });
}
Also used : SafeFuture(tech.pegasys.teku.infrastructure.async.SafeFuture) Bytes(org.apache.tuweni.bytes.Bytes) Interruptor(tech.pegasys.teku.infrastructure.async.SafeFuture.Interruptor) RemoteWriteClosed(io.libp2p.etc.util.netty.mux.RemoteWriteClosed) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) LibP2PNodeId(tech.pegasys.teku.networking.p2p.libp2p.LibP2PNodeId) ByteBuf(io.netty.buffer.ByteBuf) RpcResponseHandler(tech.pegasys.teku.networking.p2p.rpc.RpcResponseHandler) Controller(tech.pegasys.teku.networking.p2p.libp2p.rpc.RpcHandler.Controller) P2PChannel(io.libp2p.core.P2PChannel) Duration(java.time.Duration) StreamPromise(io.libp2p.core.StreamPromise) ProtocolBinding(io.libp2p.core.multistream.ProtocolBinding) ProtocolDescriptor(io.libp2p.core.multistream.ProtocolDescriptor) RpcStream(tech.pegasys.teku.networking.p2p.rpc.RpcStream) AsyncRunner(tech.pegasys.teku.infrastructure.async.AsyncRunner) Connection(io.libp2p.core.Connection) Stream(io.libp2p.core.Stream) Throwables(com.google.common.base.Throwables) PeerDisconnectedException(tech.pegasys.teku.networking.p2p.peer.PeerDisconnectedException) RpcRequestHandler(tech.pegasys.teku.networking.p2p.rpc.RpcRequestHandler) FutureUtil.ignoreFuture(tech.pegasys.teku.infrastructure.async.FutureUtil.ignoreFuture) Consumer(java.util.function.Consumer) RpcMethod(tech.pegasys.teku.networking.p2p.rpc.RpcMethod) StreamClosedException(tech.pegasys.teku.networking.p2p.rpc.StreamClosedException) ExceptionUtil(tech.pegasys.teku.infrastructure.exceptions.ExceptionUtil) StreamTimeoutException(tech.pegasys.teku.networking.p2p.rpc.StreamTimeoutException) Logger(org.apache.logging.log4j.Logger) SimpleChannelInboundHandler(io.netty.channel.SimpleChannelInboundHandler) Optional(java.util.Optional) VisibleForTesting(com.google.common.annotations.VisibleForTesting) NotNull(org.jetbrains.annotations.NotNull) LogManager(org.apache.logging.log4j.LogManager) NodeId(tech.pegasys.teku.networking.p2p.peer.NodeId) ConnectionClosedException(io.libp2p.core.ConnectionClosedException) RpcStreamController(tech.pegasys.teku.networking.p2p.rpc.RpcStreamController) Bytes(org.apache.tuweni.bytes.Bytes) Interruptor(tech.pegasys.teku.infrastructure.async.SafeFuture.Interruptor) SafeFuture(tech.pegasys.teku.infrastructure.async.SafeFuture) ConnectionClosedException(io.libp2p.core.ConnectionClosedException) RpcStream(tech.pegasys.teku.networking.p2p.rpc.RpcStream) Stream(io.libp2p.core.Stream) PeerDisconnectedException(tech.pegasys.teku.networking.p2p.peer.PeerDisconnectedException) PeerDisconnectedException(tech.pegasys.teku.networking.p2p.peer.PeerDisconnectedException) StreamClosedException(tech.pegasys.teku.networking.p2p.rpc.StreamClosedException) StreamTimeoutException(tech.pegasys.teku.networking.p2p.rpc.StreamTimeoutException) ConnectionClosedException(io.libp2p.core.ConnectionClosedException) StreamTimeoutException(tech.pegasys.teku.networking.p2p.rpc.StreamTimeoutException)

Aggregations

VisibleForTesting (com.google.common.annotations.VisibleForTesting)1 Throwables (com.google.common.base.Throwables)1 Connection (io.libp2p.core.Connection)1 ConnectionClosedException (io.libp2p.core.ConnectionClosedException)1 P2PChannel (io.libp2p.core.P2PChannel)1 Stream (io.libp2p.core.Stream)1 StreamPromise (io.libp2p.core.StreamPromise)1 ProtocolBinding (io.libp2p.core.multistream.ProtocolBinding)1 ProtocolDescriptor (io.libp2p.core.multistream.ProtocolDescriptor)1 RemoteWriteClosed (io.libp2p.etc.util.netty.mux.RemoteWriteClosed)1 ByteBuf (io.netty.buffer.ByteBuf)1 ChannelHandlerContext (io.netty.channel.ChannelHandlerContext)1 SimpleChannelInboundHandler (io.netty.channel.SimpleChannelInboundHandler)1 Duration (java.time.Duration)1 Optional (java.util.Optional)1 Consumer (java.util.function.Consumer)1 LogManager (org.apache.logging.log4j.LogManager)1 Logger (org.apache.logging.log4j.Logger)1 Bytes (org.apache.tuweni.bytes.Bytes)1 NotNull (org.jetbrains.annotations.NotNull)1