/** * Marks this future as successfully completed. * <p> * This is a shortcut for {@code success(null)}, which further shows, that the matter of successful * completion is important, not the resulting object of a computation. * * @return <tt>this</tt> for fluent method chaining */ public Future success() { success(null); return this; }
@Override public void initialize() throws Exception { readyFuture = new Future(); } }
/** * Adds a completion handler to this promise which only handles the successful completion of the promise. * <p> * If the promise is already completed, the handler is immediately invoked. * * @param successHandler the handler to be notified once the promise is completed. A promise can notify more than * one handler. * @return <tt>this</tt> for fluent method chaining */ public Future onSuccess(Runnable successHandler) { onSuccess(ignored -> successHandler.run()); return this; } }
@Override public void onFailure(Throwable throwable) throws Exception { semaphore.release(); if (!completionFuture.isCompleted()) { completionFuture.fail(throwable); } } });
protected void drop() { if (dropHandler != null) { dropHandler.run(); } promise.doNotLogErrors(); promise.fail(new RejectedExecutionException()); } }
@Override public void onSuccess(@Nullable Object value) throws Exception { semaphore.release(); if (!completionFuture.isCompleted()) { if (promisesOpen.decrementAndGet() == 0) { completionFuture.success(); } } }
@Override public void run() { try { Watch w = Watch.start(); try { if (ctx == null) { CallContext.initialize(); } else { CallContext.setCurrent(ctx); } TaskContext.get().setSystem(SYSTEM_ASYNC).setSubSystem(category).setJob(String.valueOf(jobNumber)); runnable.run(); promise.success(null); } finally { CallContext.detach(); durationAverage.addValue(w.elapsedMillis()); } } catch (Exception t) { Exceptions.handle(Tasks.LOG, t); promise.fail(t); } }
public void add(Promise<?> promise) { if (completionFuture.isCompleted()) { completionFuture = new Future();
/** * Transforms a collection of items into a promise for a list of results while invoking an async function for * each item. * * @param input the items to iterate over * @param toPromiseHandler the async function which returns a promise to indicate completion * @param <I> the input type * @param <O> the output type generated by the async function * @return a promise containing the invocation results of the async function for each item in the input */ public static <I, O> Promise<List<O>> sequence(Iterable<I> input, Function<I, Promise<O>> toPromiseHandler) { Promise<List<O>> result = new Promise<>(); List<O> buffer = new ArrayList<>(); processChain(input, toPromiseHandler, (ignored, output) -> buffer.add(output)).onSuccess(() -> result.success( buffer)).onFailure(result::fail); return result; }
private static void stopLifecycleParticipants() { LOG.INFO("Stopping lifecycles..."); LOG.INFO(SEPARATOR_LINE); for (int i = lifecycleStopParticipants.size() - 1; i >= 0; i--) { Stoppable stoppable = lifecycleStopParticipants.get(i); Future future = tasks.defaultExecutor().fork(() -> stopLifecycle(stoppable)); if (!future.await(Duration.ofSeconds(10))) { LOG.WARN("Lifecycle '%s' did not stop within 10 seconds....", stoppable.getClass().getName()); } } LOG.INFO(SEPARATOR_LINE); }
@Override public void onFailure(Throwable throwable) { future.fail(throwable); } });
private static void startComponents() { if (started) { stop(); } boolean startFailed = false; for (final Startable lifecycle : lifecycleStartParticipants) { Future future = tasks.defaultExecutor().fork(() -> startLifecycle(lifecycle)); if (!future.await(Duration.ofMinutes(1))) { LOG.WARN("Lifecycle '%s' did not start within one minute....", lifecycle.getClass().getName()); startFailed = true; } } if (startFailed) { outputActiveOperations(); } started = true; }
@Override public void onSuccess(V value) throws Exception { future.success(); }
/** * Iterates over the given input and invokes an async function for each element. * <p> * Note that this is done sequentially, therefore only one call happens at a time * * @param items the items to iterate over * @param toPromiseHandler the async function which returns a promise to indicate completion * @param resultConsumer the handler used to collect the results * @param <I> the input type * @param <O> the output type generated by the async function * @return a future which is fulfilled once all items have been processer or failed if one item fails */ public static <I, O> Future processChain(Iterable<I> items, Function<I, Promise<O>> toPromiseHandler, BiConsumer<I, O> resultConsumer) { Future result = new Future(); processChain(items.iterator(), toPromiseHandler, resultConsumer, result); return result; }
/** * Determines if the framework is ready yet. * * @return <tt>true</tt> if the framework is ready, <tt>false</tt> otherwise. */ public boolean isReady() { if (ready == null) { if (schema == null) { return false; } ready = Boolean.FALSE; getReadyFuture().onSuccess(o -> ready = Boolean.TRUE); } return ready.booleanValue(); }
private static <I, O> void processChain(Iterator<I> iter, Function<I, Promise<O>> toPromiseHandler, BiConsumer<I, O> resultConsumer, Future completionFuture) { if (!iter.hasNext()) { completionFuture.success(); return; } I item = iter.next(); toPromiseHandler.apply(item).onSuccess(result -> { resultConsumer.accept(item, result); processChain(iter, toPromiseHandler, resultConsumer, completionFuture); }).onFailure(completionFuture::fail); }
protected void startup() { try (Operation op = new Operation(() -> "IndexLifecycle.startClient", Duration.ofSeconds(15))) { startClient(); } schema = new Schema(this); schema.load(); try (Operation op = new Operation(() -> "IndexLifecycle.updateMappings", Duration.ofSeconds(30))) { updateMappings(); } ready = true; readyFuture.success(); delayLineTimer = new Timer("index-delay"); delayLineTimer.schedule(new DelayLineHandler(), 1000, 1000); }
@Override public void started() { if (!elastic.isConfigured()) { return; } Elastic.LOG.INFO("Elastic is starting up and checking the database schema..."); int numSuccess = 0; int numFailed = 0; for (EntityDescriptor ed : mixing.getDesciptors()) { if (ElasticEntity.class.isAssignableFrom(ed.getType())) { if (setupEntity(ed)) { numSuccess++; } else { numFailed++; } } } Elastic.LOG.INFO("Setup completed: Updated %s indices / %s failures occurred", numSuccess, numFailed); elastic.readyFuture.success(); }
readyFuture.success();