Search in sources :

Example 81 with ClientConnection

use of io.pravega.client.connection.impl.ClientConnection in project pravega by pravega.

the class SegmentOutputStreamImpl method write.

/**
 * @see SegmentOutputStream#write(PendingEvent)
 */
@Override
public void write(PendingEvent event) {
    // State is set to sealed during a Transaction abort and the segment writer should not throw an {@link IllegalStateException} in such a case.
    checkState(!state.isAlreadySealed() || NameUtils.isTransactionSegment(segmentName), "Segment: %s is already sealed", segmentName);
    synchronized (writeOrderLock) {
        ClientConnection connection;
        try {
            // if connection is null getConnection() establishes a connection and retransmits all events in inflight
            // list.
            connection = Futures.getThrowingException(getConnection());
        } catch (SegmentSealedException | NoSuchSegmentException e) {
            // Add the event to inflight, this will be resent to the successor during the execution of resendToSuccessorsCallback
            state.addToInflight(event);
            return;
        } catch (RetriesExhaustedException e) {
            event.getAckFuture().completeExceptionally(e);
            log.error("Failed to write event to Pravega due connectivity error ", e);
            return;
        }
        long eventNumber = state.addToInflight(event);
        try {
            Append append = new Append(segmentName, writerId, eventNumber, event.getEventCount(), event.getData(), null, requestId);
            log.trace("Sending append request: {}", append);
            connection.send(append);
        } catch (ConnectionFailedException e) {
            log.warn("Failed writing event through writer " + writerId + " due to: ", e);
            // As the message is inflight, this will perform the retransmission.
            reconnect();
        }
    }
}
Also used : Append(io.pravega.shared.protocol.netty.Append) SetupAppend(io.pravega.shared.protocol.netty.WireCommands.SetupAppend) RetriesExhaustedException(io.pravega.common.util.RetriesExhaustedException) ClientConnection(io.pravega.client.connection.impl.ClientConnection) ConnectionFailedException(io.pravega.shared.protocol.netty.ConnectionFailedException)

Example 82 with ClientConnection

use of io.pravega.client.connection.impl.ClientConnection in project pravega by pravega.

the class SegmentOutputStreamImpl method flush.

/**
 * @see SegmentOutputStream#flush()
 */
@Override
public void flush() throws SegmentSealedException {
    int numInflight = state.getNumInflight();
    log.debug("Flushing writer: {} with {} inflight events", writerId, numInflight);
    if (numInflight != 0) {
        try {
            ClientConnection connection = Futures.getThrowingException(getConnection());
            connection.send(new KeepAlive());
        } catch (SegmentSealedException | NoSuchSegmentException e) {
            if (NameUtils.isTransactionSegment(segmentName)) {
                log.warn("Exception observed during a flush on a transaction segment, this indicates that the transaction is " + "committed/aborted. Details: {}", e.getMessage());
                failConnection(e);
            } else {
                log.info("Exception observed while obtaining connection during flush. Details: {} ", e.getMessage());
            }
        } catch (Exception e) {
            failConnection(e);
            if (e instanceof RetriesExhaustedException) {
                log.error("Flush on segment {} by writer {} failed after all retries", segmentName, writerId);
                // throw an exception to the external world that the flush failed due to RetriesExhaustedException
                throw Exceptions.sneakyThrow(e);
            }
        }
        state.waitForInflight();
        Exceptions.checkNotClosed(state.isClosed(), this);
        /* SegmentSealedException is thrown if either of the below conditions are true
                 - resendToSuccessorsCallback has been invoked.
                 - the segment corresponds to an aborted Transaction.
             */
        if (state.needSuccessors.get() || (NameUtils.isTransactionSegment(segmentName) && state.isAlreadySealed())) {
            throw new SegmentSealedException(segmentName + " sealed for writer " + writerId);
        }
    } else if (state.exception instanceof RetriesExhaustedException) {
        // All attempts to connect with SSS have failed.
        // The number of retry attempts is based on EventWriterConfig
        log.error("Flush on segment {} by writer {} failed after all retries", segmentName, writerId);
        throw Exceptions.sneakyThrow(state.exception);
    }
}
Also used : RetriesExhaustedException(io.pravega.common.util.RetriesExhaustedException) KeepAlive(io.pravega.shared.protocol.netty.WireCommands.KeepAlive) ClientConnection(io.pravega.client.connection.impl.ClientConnection) TokenExpiredException(io.pravega.auth.TokenExpiredException) RetriesExhaustedException(io.pravega.common.util.RetriesExhaustedException) ConnectionFailedException(io.pravega.shared.protocol.netty.ConnectionFailedException) InvalidTokenException(io.pravega.auth.InvalidTokenException)

Example 83 with ClientConnection

use of io.pravega.client.connection.impl.ClientConnection in project pravega by pravega.

the class MockConnectionFactoryImpl method establishConnection.

@Override
@Synchronized
public CompletableFuture<ClientConnection> establishConnection(PravegaNodeUri location, ReplyProcessor rp) {
    ClientConnection connection = connections.get(location);
    Preconditions.checkState(connection != null, "Unexpected Endpoint");
    ReplyProcessor previous = processors.put(location, rp);
    assertNull("Mock connection factory does not support multiple concurrent connections to the same location", previous);
    return CompletableFuture.completedFuture(new DelegateClientConnection(location, connection));
}
Also used : ClientConnection(io.pravega.client.connection.impl.ClientConnection) ReplyProcessor(io.pravega.shared.protocol.netty.ReplyProcessor) Synchronized(lombok.Synchronized)

Example 84 with ClientConnection

use of io.pravega.client.connection.impl.ClientConnection in project pravega by pravega.

the class LargeEventWriterTest method testPipelining.

@Test(timeout = 5000)
public void testPipelining() throws NoSuchSegmentException, AuthenticationException, SegmentSealedException, ConnectionFailedException {
    Segment segment = Segment.fromScopedName("foo/bar/1");
    MockConnectionFactoryImpl connectionFactory = new MockConnectionFactoryImpl();
    MockController controller = new MockController("localhost", 0, connectionFactory, false);
    ClientConnection connection = Mockito.mock(ClientConnection.class);
    PravegaNodeUri location = new PravegaNodeUri("localhost", 0);
    connectionFactory.provideConnection(location, connection);
    ArrayList<ByteBuffer> buffers = new ArrayList<>();
    buffers.add(ByteBuffer.allocate(Serializer.MAX_EVENT_SIZE - WireCommands.TYPE_PLUS_LENGTH_SIZE));
    buffers.add(ByteBuffer.allocate(Serializer.MAX_EVENT_SIZE - WireCommands.TYPE_PLUS_LENGTH_SIZE));
    buffers.add(ByteBuffer.allocate(Serializer.MAX_EVENT_SIZE - WireCommands.TYPE_PLUS_LENGTH_SIZE));
    ArrayList<ConditionalBlockEnd> written = new ArrayList<>();
    answerRequest(connectionFactory, connection, location, CreateTransientSegment.class, r -> new SegmentCreated(r.getRequestId(), "transient-segment"));
    answerRequest(connectionFactory, connection, location, SetupAppend.class, r -> new AppendSetup(r.getRequestId(), segment.getScopedName(), r.getWriterId(), WireCommands.NULL_ATTRIBUTE_VALUE));
    // If appends are not pipelined, the call to writeLargeEvents will stall waiting for the first reply.
    Mockito.doAnswer(new Answer<Void>() {

        @Override
        public Void answer(InvocationOnMock invocation) throws Throwable {
            ConditionalBlockEnd argument = (ConditionalBlockEnd) invocation.getArgument(0);
            written.add(argument);
            if (written.size() == buffers.size()) {
                for (ConditionalBlockEnd append : written) {
                    connectionFactory.getProcessor(location).process(new DataAppended(append.getRequestId(), writerId, append.getEventNumber(), append.getEventNumber() - 1, append.getExpectedOffset() + append.getData().readableBytes()));
                }
            }
            return null;
        }
    }).when(connection).send(any(ConditionalBlockEnd.class));
    answerRequest(connectionFactory, connection, location, MergeSegments.class, r -> {
        return new SegmentsMerged(r.getRequestId(), r.getSource(), r.getTarget(), -1);
    });
    LargeEventWriter writer = new LargeEventWriter(writerId, controller, connectionFactory);
    EmptyTokenProviderImpl tokenProvider = new EmptyTokenProviderImpl();
    writer.writeLargeEvent(segment, buffers, tokenProvider, EventWriterConfig.builder().build());
}
Also used : ArrayList(java.util.ArrayList) ByteBuffer(java.nio.ByteBuffer) Segment(io.pravega.client.segment.impl.Segment) NoSuchSegment(io.pravega.shared.protocol.netty.WireCommands.NoSuchSegment) CreateTransientSegment(io.pravega.shared.protocol.netty.WireCommands.CreateTransientSegment) AppendSetup(io.pravega.shared.protocol.netty.WireCommands.AppendSetup) SegmentCreated(io.pravega.shared.protocol.netty.WireCommands.SegmentCreated) EmptyTokenProviderImpl(io.pravega.client.security.auth.EmptyTokenProviderImpl) ConditionalBlockEnd(io.pravega.shared.protocol.netty.WireCommands.ConditionalBlockEnd) PravegaNodeUri(io.pravega.shared.protocol.netty.PravegaNodeUri) InvocationOnMock(org.mockito.invocation.InvocationOnMock) DataAppended(io.pravega.shared.protocol.netty.WireCommands.DataAppended) MockConnectionFactoryImpl(io.pravega.client.stream.mock.MockConnectionFactoryImpl) MockController(io.pravega.client.stream.mock.MockController) ClientConnection(io.pravega.client.connection.impl.ClientConnection) SegmentsMerged(io.pravega.shared.protocol.netty.WireCommands.SegmentsMerged) Test(org.junit.Test)

Example 85 with ClientConnection

use of io.pravega.client.connection.impl.ClientConnection in project pravega by pravega.

the class LargeEventWriterTest method testRetries.

@Test(timeout = 5000)
public void testRetries() throws ConnectionFailedException, NoSuchSegmentException, AuthenticationException {
    Segment segment = Segment.fromScopedName("foo/bar/1");
    MockConnectionFactoryImpl connectionFactory = new MockConnectionFactoryImpl();
    MockController controller = new MockController("localhost", 0, connectionFactory, false);
    ClientConnection connection = Mockito.mock(ClientConnection.class);
    PravegaNodeUri location = new PravegaNodeUri("localhost", 0);
    connectionFactory.provideConnection(location, connection);
    AtomicInteger count = new AtomicInteger(0);
    answerRequest(connectionFactory, connection, location, CreateTransientSegment.class, r -> new SegmentCreated(r.getRequestId(), "transient-segment"));
    answerRequest(connectionFactory, connection, location, SetupAppend.class, r -> new AppendSetup(r.getRequestId(), segment.getScopedName(), r.getWriterId(), WireCommands.NULL_ATTRIBUTE_VALUE));
    answerRequest(connectionFactory, connection, location, ConditionalBlockEnd.class, r -> {
        count.getAndIncrement();
        return new WrongHost(r.getRequestId(), segment.getScopedName(), null, null);
    });
    LargeEventWriter writer = new LargeEventWriter(writerId, controller, connectionFactory);
    EmptyTokenProviderImpl tokenProvider = new EmptyTokenProviderImpl();
    ArrayList<ByteBuffer> buffers = new ArrayList<>();
    buffers.add(ByteBuffer.allocate(5));
    AssertExtensions.assertThrows(RetriesExhaustedException.class, () -> writer.writeLargeEvent(segment, buffers, tokenProvider, EventWriterConfig.builder().initialBackoffMillis(1).backoffMultiple(1).enableLargeEvents(true).retryAttempts(7).build()));
    assertEquals(8, count.get());
}
Also used : ArrayList(java.util.ArrayList) WrongHost(io.pravega.shared.protocol.netty.WireCommands.WrongHost) ByteBuffer(java.nio.ByteBuffer) Segment(io.pravega.client.segment.impl.Segment) NoSuchSegment(io.pravega.shared.protocol.netty.WireCommands.NoSuchSegment) CreateTransientSegment(io.pravega.shared.protocol.netty.WireCommands.CreateTransientSegment) AppendSetup(io.pravega.shared.protocol.netty.WireCommands.AppendSetup) SegmentCreated(io.pravega.shared.protocol.netty.WireCommands.SegmentCreated) EmptyTokenProviderImpl(io.pravega.client.security.auth.EmptyTokenProviderImpl) PravegaNodeUri(io.pravega.shared.protocol.netty.PravegaNodeUri) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) MockConnectionFactoryImpl(io.pravega.client.stream.mock.MockConnectionFactoryImpl) MockController(io.pravega.client.stream.mock.MockController) ClientConnection(io.pravega.client.connection.impl.ClientConnection) Test(org.junit.Test)

Aggregations

ClientConnection (io.pravega.client.connection.impl.ClientConnection)87 PravegaNodeUri (io.pravega.shared.protocol.netty.PravegaNodeUri)81 MockController (io.pravega.client.stream.mock.MockController)79 MockConnectionFactoryImpl (io.pravega.client.stream.mock.MockConnectionFactoryImpl)78 Test (org.junit.Test)77 Cleanup (lombok.Cleanup)51 InvocationOnMock (org.mockito.invocation.InvocationOnMock)43 WireCommands (io.pravega.shared.protocol.netty.WireCommands)40 SetupAppend (io.pravega.shared.protocol.netty.WireCommands.SetupAppend)35 AppendSetup (io.pravega.shared.protocol.netty.WireCommands.AppendSetup)34 UUID (java.util.UUID)34 ReplyProcessor (io.pravega.shared.protocol.netty.ReplyProcessor)33 ByteBuffer (java.nio.ByteBuffer)31 CompletableFuture (java.util.concurrent.CompletableFuture)30 InOrder (org.mockito.InOrder)27 Append (io.pravega.shared.protocol.netty.Append)23 ConnectionFailedException (io.pravega.shared.protocol.netty.ConnectionFailedException)23 Answer (org.mockito.stubbing.Answer)17 ScheduledExecutorService (java.util.concurrent.ScheduledExecutorService)16 ArrayList (java.util.ArrayList)14