@Override public SegmentOutputStream createOutputStreamForSegment(Segment segment, Consumer<Segment> segmentSealedCallback, EventWriterConfig config, String delegationToken) { SegmentOutputStreamImpl result = new SegmentOutputStreamImpl(segment.getScopedName(), controller, cf, UUID.randomUUID(), segmentSealedCallback, getRetryFromConfig(config), delegationToken); try { result.getConnection(); } catch (RetriesExhaustedException | SegmentSealedException | NoSuchSegmentException e) { log.warn("Initial connection attempt failure. Suppressing.", e); } return result; }
connection = Futures.getThrowingException(getConnection()); } catch (SegmentSealedException | NoSuchSegmentException e) {
/** * @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 (Exception e) { failConnection(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() || (StreamSegmentNameUtils.isTransactionSegment(segmentName) && state.isAlreadySealed())) { throw new SegmentSealedException(segmentName + " sealed for writer " + writerId); } } }
@Test(timeout = 10000) public void testConnectAndFailedSetupAppendDueToTruncation() throws Exception { AtomicBoolean callbackInvoked = new AtomicBoolean(); Consumer<Segment> resendToSuccessorsCallback = segment -> { callbackInvoked.set(true); }; UUID cid = UUID.randomUUID(); PravegaNodeUri uri = new PravegaNodeUri("endpoint", SERVICE_PORT); MockConnectionFactoryImpl cf = new MockConnectionFactoryImpl(); ScheduledExecutorService executor = mock(ScheduledExecutorService.class); implementAsDirectExecutor(executor); // Ensure task submitted to executor is run inline. cf.setExecutor(executor); MockController controller = new MockController(uri.getEndpoint(), uri.getPort(), cf); ClientConnection connection = mock(ClientConnection.class); cf.provideConnection(uri, connection); @Cleanup SegmentOutputStreamImpl output = new SegmentOutputStreamImpl(SEGMENT, controller, cf, cid, resendToSuccessorsCallback, RETRY_SCHEDULE, ""); output.reconnect(); verify(connection).send(new SetupAppend(1, cid, SEGMENT, "")); cf.getProcessor(uri).noSuchSegment(new WireCommands.NoSuchSegment(1, SEGMENT, "SomeException")); CompletableFuture<ClientConnection> connectionFuture = output.getConnection(); assertThrows(NoSuchSegmentException.class, () -> Futures.getThrowingException(connectionFuture)); assertTrue(callbackInvoked.get()); }