Search in sources :

Example 1 with Interruptor

use of tech.pegasys.teku.infrastructure.async.SafeFuture.Interruptor in project teku by ConsenSys.

the class SafeFutureTest method notInterrupted_shouldThrowIfInterrupted.

@Test
public void notInterrupted_shouldThrowIfInterrupted() {
    SafeFuture<Void> interruptorFut = new SafeFuture<>();
    Interruptor interruptor = SafeFuture.createInterruptor(interruptorFut, () -> new RuntimeException("test"));
    interruptorFut.complete(null);
    SafeFuture<String> future = SafeFuture.notInterrupted(interruptor).thenApply(__ -> "aaa");
    assertThatThrownBy(future::get).hasMessageContaining("test");
}
Also used : Interruptor(tech.pegasys.teku.infrastructure.async.SafeFuture.Interruptor) SafeFutureAssert.assertThatSafeFuture(tech.pegasys.teku.infrastructure.async.SafeFutureAssert.assertThatSafeFuture) Test(org.junit.jupiter.api.Test)

Example 2 with Interruptor

use of tech.pegasys.teku.infrastructure.async.SafeFuture.Interruptor 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)

Example 3 with Interruptor

use of tech.pegasys.teku.infrastructure.async.SafeFuture.Interruptor in project teku by ConsenSys.

the class SafeFutureTest method orInterrupt_simpleCompleteWithoutInterruption.

@Test
public void orInterrupt_simpleCompleteWithoutInterruption() throws Exception {
    SafeFuture<Integer> interruptorFut = new SafeFuture<>();
    Interruptor interruptor = SafeFuture.createInterruptor(interruptorFut, IllegalStateException::new);
    SafeFuture<Integer> fut0 = new SafeFuture<>();
    assertThat(hasDependents(interruptorFut)).isFalse();
    assertThat(hasDependents(fut0)).isFalse();
    SafeFuture<Integer> intFut = fut0.orInterrupt(interruptor);
    assertThat(hasDependents(interruptorFut)).isTrue();
    assertThat(hasDependents(fut0)).isTrue();
    fut0.complete(12);
    assertThat(hasDependents(interruptorFut)).isFalse();
    assertThat(hasDependents(fut0)).isFalse();
    assertThat(intFut.get()).isEqualTo(12);
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Interruptor(tech.pegasys.teku.infrastructure.async.SafeFuture.Interruptor) SafeFutureAssert.assertThatSafeFuture(tech.pegasys.teku.infrastructure.async.SafeFutureAssert.assertThatSafeFuture) Test(org.junit.jupiter.api.Test)

Example 4 with Interruptor

use of tech.pegasys.teku.infrastructure.async.SafeFuture.Interruptor in project teku by ConsenSys.

the class SafeFutureTest method orInterrupt_triggerOneOfTwoInterruptors.

@Test
public void orInterrupt_triggerOneOfTwoInterruptors() {
    SafeFuture<Integer> interruptorFut1 = new SafeFuture<>();
    SafeFuture<Integer> interruptorFut2 = new SafeFuture<>();
    Interruptor interruptor1 = SafeFuture.createInterruptor(interruptorFut1, IllegalStateException::new);
    Interruptor interruptor2 = SafeFuture.createInterruptor(interruptorFut2, IllegalStateException::new);
    SafeFuture<Integer> fut0 = new SafeFuture<>();
    assertThat(hasDependents(interruptorFut1)).isFalse();
    assertThat(hasDependents(interruptorFut2)).isFalse();
    assertThat(hasDependents(fut0)).isFalse();
    SafeFuture<Integer> intFut = fut0.orInterrupt(interruptor1, interruptor2);
    assertThat(hasDependents(interruptorFut1)).isTrue();
    assertThat(hasDependents(interruptorFut2)).isTrue();
    assertThat(hasDependents(fut0)).isTrue();
    interruptorFut2.complete(0);
    assertThat(hasDependents(interruptorFut1)).isFalse();
    assertThat(hasDependents(interruptorFut2)).isFalse();
    assertThat(hasDependents(fut0)).isFalse();
    assertThat(intFut).isCompletedExceptionally();
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Interruptor(tech.pegasys.teku.infrastructure.async.SafeFuture.Interruptor) SafeFutureAssert.assertThatSafeFuture(tech.pegasys.teku.infrastructure.async.SafeFutureAssert.assertThatSafeFuture) Test(org.junit.jupiter.api.Test)

Aggregations

Interruptor (tech.pegasys.teku.infrastructure.async.SafeFuture.Interruptor)4 Test (org.junit.jupiter.api.Test)3 SafeFutureAssert.assertThatSafeFuture (tech.pegasys.teku.infrastructure.async.SafeFutureAssert.assertThatSafeFuture)3 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)2 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