private CompletableFuture<Void> checkReady() { if (!ready) { return Futures.failedFuture(new IllegalStateException(getClass().getName() + " not yet ready")); } else { return CompletableFuture.completedFuture(null); } }
@Override public CompletableFuture<Long> sealStreamSegment(String streamSegmentName, Duration timeout) { CompletableFuture<Long> result = impl.sealStreamSegment(streamSegmentName, timeout); Futures.await(result); return result; }
public CompletableFuture<Void> notifyDeleteSegments(String scope, String stream, Set<Long> segmentsToDelete, String delegationToken, long requestId) { return Futures.allOf(segmentsToDelete .stream() .parallel() .map(segment -> notifyDeleteSegment(scope, stream, segment, delegationToken, requestId)) .collect(Collectors.toList())); }
public static CompletableFuture<Void> loopWithDelay(Supplier<Boolean> condition, Supplier<CompletableFuture<Void>> loopBody, long delay, ScheduledExecutorService executor) { return Futures.loop(condition, () -> Futures.delayedFuture(loopBody, delay, executor), executor); }
private CompletableFuture<Void> clearMarkers(final Set<Long> segments) { return Futures.toVoid(Futures.allOfWithResults(segments.stream().parallel() .map(this::removeColdMarker).collect(Collectors.toList()))); }
@Override public CompletableFuture<Void> handleFailedProcess(String failedHost) { if (!transactionMetadataTasks.isReady()) { return Futures.failedFuture(new IllegalStateException(getClass().getName() + " not yet ready")); } log.info("Host={}, sweeping orphaned transactions", failedHost); CompletableFuture<Void> delay = Futures.delayedFuture(Duration.ofMillis(2 * maxTxnTimeoutMillis), executor); return delay.thenComposeAsync(x -> withRetriesAsync(() -> sweepOrphanedTxnsWithoutDelay(failedHost), RETRYABLE_PREDICATE, Integer.MAX_VALUE, executor)); }
@Override protected CompletableFuture<Void> run() { this.canContinue.set(true); return Futures.loop( this::canLoop, this::runOneIteration, this.executorService); }
void waitForTxnsToComplete() { log.info("Wait for txns to complete"); if (!Futures.await(Futures.allOf(testState.txnStatusFutureList))) { log.error("Transaction futures did not complete with exceptions"); } // check for exceptions during transaction commits if (testState.getTxnWriteException.get() != null) { log.info("Unable to commit transaction:", testState.getTxnWriteException.get()); fail("Unable to commit transaction. Test failure"); } }
CompletableFuture<List<TableEntry>> getResultFutures() { return Futures.allOfWithResults(this.resultFutures); } }
/** * Executes the asynchronous task after the specified delay. * * @param task Asynchronous task. * @param delay Delay in milliseconds. * @param executorService Executor on which to execute the task. * @param <T> Type parameter. * @return A CompletableFuture that will be completed with the result of the given task. */ public static <T> CompletableFuture<T> delayedFuture(final Supplier<CompletableFuture<T>> task, final long delay, final ScheduledExecutorService executorService) { return delayedFuture(Duration.ofMillis(delay), executorService) .thenCompose(v -> task.get()); }
private void checkScaleStatus(CompletableFuture<Boolean> scaleStatus) { Futures.exceptionListener(scaleStatus, t -> log.error("Scale Operation completed with an error", t)); if (Futures.await(scaleStatus, SCALE_WAIT_SECONDS)) { log.info("Scale operation has completed: {}", scaleStatus.join()); if (!scaleStatus.join()) { log.error("Scale operation did not complete", scaleStatus.join()); Assert.fail("Scale operation did not complete successfully"); } } else { Assert.fail("Scale operation threw an exception"); } }
private void createWritersInternal(EventStreamClientFactory clientFactory, final int writers, String scope, String stream, CompletableFuture<Void> writersComplete) { testState.writersListComplete.add(writersComplete); log.info("Client factory details {}", clientFactory.toString()); log.info("Creating {} writers", writers); List<CompletableFuture<Void>> writerFutureList = new ArrayList<>(); log.info("Writers writing in the scope {}", scope); CompletableFuture.runAsync(() -> { for (int i = 0; i < writers; i++) { log.info("Starting writer{}", i); final EventStreamWriter<String> tmpWriter = instantiateWriter(clientFactory, stream); final CompletableFuture<Void> writerFuture = startWriting(tmpWriter); Futures.exceptionListener(writerFuture, t -> log.error("Error while writing events:", t)); writerFutureList.add(writerFuture); } }, executorService).thenRun(() -> { testState.writers.addAll(writerFutureList); Futures.completeAfter(() -> Futures.allOf(writerFutureList), writersComplete); Futures.exceptionListener(writersComplete, t -> log.error("Exception while waiting for writers to complete", t)); }); }
private boolean dataWaitingToGoInBuffer() { return outstandingRequest != null && Futures.isSuccessful(outstandingRequest) && buffer.capacityAvailable() > 0; }
@Override public void send(WireCommand cmd) throws ConnectionFailedException { recentMessage.set(true); Futures.getAndHandleExceptions(getChannel().writeAndFlush(cmd), ConnectionFailedException::new); }
@Override public CompletableFuture<Map<String, Data>> getTxnInEpoch(int epoch) { return Futures.exceptionallyExpecting(store.getChildren(getEpochPath(epoch)), e -> Exceptions.unwrap(e) instanceof StoreException.DataNotFoundException, Collections.emptyList()) .thenCompose(txIds -> Futures.allOfWithResults(txIds.stream().collect( Collectors.toMap(txId -> txId, txId -> Futures.exceptionallyExpecting(store.getData(getActiveTxPath(epoch, txId)), e -> Exceptions.unwrap(e) instanceof StoreException.DataNotFoundException, EMPTY_DATA))) ).thenApply(txnMap -> txnMap.entrySet().stream().filter(x -> !x.getValue().equals(EMPTY_DATA)) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))) ); }
/** * Attaches the given callback as an exception listener to the given CompletableFuture, which will be invoked when * the future times out (fails with a TimeoutException). * * @param future The future to attach to. * @param callback The callback to invoke. * @param <T> The Type of the future's result. */ public static <T> void onTimeout(CompletableFuture<T> future, Consumer<TimeoutException> callback) { exceptionListener(future, TimeoutException.class, callback); }
@Override public CompletableFuture<Void> deleteStreamCutBefore(StreamCutReferenceRecord record) { return getRetentionSetData() .thenCompose(data -> { RetentionSet retention = RetentionSet.fromBytes(data.getData()); RetentionSet update = RetentionSet.removeStreamCutBefore(retention, record); List<StreamCutReferenceRecord> toRemove = retention.retentionRecordsBefore(record); return Futures.allOf(toRemove.stream().map(x -> deleteStreamCutRecordData(x.getRecordingTime())).collect(Collectors.toList())) .thenCompose(x -> Futures.toVoid(updateRetentionSetData(new Data(update.toBytes(), data.getVersion())))); }); }
/** * Triggers a number of metadata cleanups by repeatedly appending to a random new segment until a cleanup task is detected. * * @param expectedSegmentNames The segments that we are expecting to evict. */ CompletableFuture<Void> triggerMetadataCleanup(Collection<String> expectedSegmentNames) { String tempSegmentName = getSegmentName(Long.hashCode(System.nanoTime())); HashSet<String> remainingSegments = new HashSet<>(expectedSegmentNames); CompletableFuture<Void> cleanupTask = Futures.futureWithTimeout(TIMEOUT, this.executor); // Inject this callback into the MetadataCleaner callback, which was setup for us in createMetadataCleaner(). this.metadataCleanupFinishedCallback = evictedSegmentNames -> { remainingSegments.removeAll(evictedSegmentNames); if (remainingSegments.size() == 0) { cleanupTask.complete(null); } }; CompletableFuture<Void> af = appendRandomly(tempSegmentName, true, () -> !cleanupTask.isDone()); Futures.exceptionListener(af, cleanupTask::completeExceptionally); return cleanupTask; }
private CompletionStage<Void> checkDone(Supplier<CompletableFuture<Boolean>> condition) { AtomicBoolean isDone = new AtomicBoolean(false); return Futures.loop(() -> !isDone.get(), () -> Futures.delayedFuture(condition, 100, executor) .thenAccept(isDone::set), executor); }
private CompletableFuture<Void> processCatchupReads(Queue<StoreReader.ReadItem> catchupReads) { return Futures.loop( () -> !catchupReads.isEmpty(), () -> processCatchupRead(catchupReads.poll()), this.executorService); }