@Override public SegmentInputStream createInputStreamForSegment(Segment segment, String delegationToken) { AsyncSegmentInputStreamImpl async = new AsyncSegmentInputStreamImpl(controller, cf, segment, delegationToken); async.getConnection(); return new SegmentInputStreamImpl(async, 0); } }
@Override public CompletableFuture<SegmentRead> read(long offset, int length) { Exceptions.checkNotClosed(closed.get(), this); WireCommands.ReadSegment request = new WireCommands.ReadSegment(segmentId.getScopedName(), offset, length, this.delegationToken); return backoffSchedule.retryWhen(t -> { Throwable ex = Exceptions.unwrap(t); if (closed.get()) { log.debug("Exception while reading from Segment : {}", segmentId, ex); } else { log.warn("Exception while reading from Segment : {}", segmentId, ex); } return ex instanceof Exception && !(ex instanceof ConnectionClosedException) && !(ex instanceof SegmentTruncatedException); }).runAsync(() -> { return getConnection() .whenComplete((connection, ex) -> { if (ex != null) { log.warn("Exception while establishing connection with Pravega " + "node", ex); closeConnection(new ConnectionFailedException(ex)); } }).thenCompose(c -> sendRequestOverConnection(request, c)); }, connectionFactory.getInternalExecutor()); }
private void closeConnection(Exception exceptionToInflightRequests) { if (closed.get()) { log.info("Closing connection to segment: {}", segmentId); } else { log.info("Closing connection to segment {} with exception: {}", segmentId, exceptionToInflightRequests); } CompletableFuture<ClientConnection> c; synchronized (lock) { c = connection; connection = null; } if (c != null && Futures.isSuccessful(c)) { try { c.getNow(null).close(); } catch (Exception e) { log.warn("Exception tearing down connection: ", e); } } failAllInflight(exceptionToInflightRequests); }
@Test(timeout = 10000) public void testCloseAbortsRead() throws InterruptedException, ExecutionException { Segment segment = new Segment("scope", "testRetry", 4); PravegaNodeUri endpoint = new PravegaNodeUri("localhost", SERVICE_PORT); MockConnectionFactoryImpl connectionFactory = new MockConnectionFactoryImpl(); MockController controller = new MockController(endpoint.getEndpoint(), endpoint.getPort(), connectionFactory); @Cleanup AsyncSegmentInputStreamImpl in = new AsyncSegmentInputStreamImpl(controller, connectionFactory, segment, ""); ClientConnection c = mock(ClientConnection.class); connectionFactory.provideConnection(endpoint, c); in.getConnection().get(); // Make sure connection is established. CompletableFuture<SegmentRead> read = in.read(1234, 5678); assertFalse(read.isDone()); in.close(); assertThrows(ConnectionClosedException.class, () -> Futures.getThrowingException(read)); verify(c).close(); }
@Test(timeout = 10000) public void testRead() throws ConnectionFailedException { Segment segment = new Segment("scope", "testRead", 1); PravegaNodeUri endpoint = new PravegaNodeUri("localhost", SERVICE_PORT); MockConnectionFactoryImpl connectionFactory = new MockConnectionFactoryImpl(); MockController controller = new MockController(endpoint.getEndpoint(), endpoint.getPort(), connectionFactory); @Cleanup AsyncSegmentInputStreamImpl in = new AsyncSegmentInputStreamImpl(controller, connectionFactory, segment, ""); ClientConnection c = mock(ClientConnection.class); connectionFactory.provideConnection(endpoint, c); WireCommands.SegmentRead segmentRead = new WireCommands.SegmentRead(segment.getScopedName(), 1234, false, false, ByteBuffer.allocate(0)); CompletableFuture<SegmentRead> readFuture = in.read(1234, 5678); AssertExtensions.assertBlocks(() -> readFuture.get(), () -> { ReplyProcessor processor = connectionFactory.getProcessor(endpoint); processor.segmentRead(segmentRead); }); verify(c).sendAsync(Mockito.eq(new WireCommands.ReadSegment(segment.getScopedName(), 1234, 5678, "")), Mockito.any(ClientConnection.CompletedCallback.class)); assertTrue(Futures.isSuccessful(readFuture)); assertEquals(segmentRead, readFuture.join()); verifyNoMoreInteractions(c); }
@Override public void close() { log.info("Closing reader for {}", segmentId); if (closed.compareAndSet(false, true)) { closeConnection(new ConnectionClosedException()); } }
@Test(timeout = 10000) public void testWrongOffsetReturned() throws ConnectionFailedException { Segment segment = new Segment("scope", "testWrongOffsetReturned", 0); byte[] good = new byte[] { 0, 1, 2, 3, 4 }; byte[] bad = new byte[] { 9, 8, 7, 6 }; PravegaNodeUri endpoint = new PravegaNodeUri("localhost", SERVICE_PORT); MockConnectionFactoryImpl connectionFactory = new MockConnectionFactoryImpl(); MockController controller = new MockController(endpoint.getEndpoint(), endpoint.getPort(), connectionFactory); @Cleanup AsyncSegmentInputStreamImpl in = new AsyncSegmentInputStreamImpl(controller, connectionFactory, segment, ""); ClientConnection c = mock(ClientConnection.class); connectionFactory.provideConnection(endpoint, c); CompletableFuture<SegmentRead> readFuture = in.read(1234, 5678); AssertExtensions.assertBlocks(() -> readFuture.get(), () -> { ReplyProcessor processor = connectionFactory.getProcessor(endpoint); processor.segmentRead(new WireCommands.SegmentRead(segment.getScopedName(), 1235, false, false, ByteBuffer.wrap(bad))); processor.segmentRead(new WireCommands.SegmentRead(segment.getScopedName(), 1234, false, false, ByteBuffer.wrap(good))); }); verify(c).sendAsync(Mockito.eq(new WireCommands.ReadSegment(segment.getScopedName(), 1234, 5678, "")), Mockito.any(ClientConnection.CompletedCallback.class)); assertTrue(Futures.isSuccessful(readFuture)); assertEquals(ByteBuffer.wrap(good), readFuture.join().getData()); verifyNoMoreInteractions(c); }
MockController controller = new MockController(endpoint.getEndpoint(), endpoint.getPort(), connectionFactory); @Cleanup AsyncSegmentInputStreamImpl in = new AsyncSegmentInputStreamImpl(controller, connectionFactory, segment, ""); ClientConnection c = mock(ClientConnection.class); InOrder inOrder = Mockito.inOrder(c); CompletableFuture<SegmentRead> readFuture = in.read(1234, 5678); assertEquals(segmentRead, readFuture.join()); assertTrue(Futures.isSuccessful(readFuture));
private EventSegmentReader getEventSegmentReader(Segment segment, long endOffset, int bufferSize) { String delegationToken = Futures.getAndHandleExceptions(controller.getOrRefreshDelegationTokenFor(segment.getScope(), segment.getStream() .getStreamName()), RuntimeException::new); AsyncSegmentInputStreamImpl async = new AsyncSegmentInputStreamImpl(controller, cf, segment, delegationToken); async.getConnection(); return getEventSegmentReader(async, 0, endOffset, bufferSize); }
AsyncSegmentInputStreamImpl in = new AsyncSegmentInputStreamImpl(controller, connectionFactory, segment, ""); ClientConnection c = mock(ClientConnection.class); connectionFactory.provideConnection(endpoint, c); CompletableFuture<SegmentRead> readFuture = in.read(1234, 5678); CompletableFuture<SegmentRead> readFuture2 = in.read(5656, 5678); AssertExtensions.assertBlocks(() -> readFuture2.get(), () -> { ReplyProcessor processor = connectionFactory.getProcessor(endpoint);