/** * Forks the given computation and returns a {@link Promise} for the computed value. * <p> * Forks the computation, which means that the current <tt>CallContext</tt> is transferred to the new thread, * and returns the result of the computation as promise. * <p> * If the executor for the given category is saturated (all threads are active and the queue is full) this * will drop the computation and the promise will be sent a <tt>RejectedExecutionException</tt>. * * @param category the category which implies which executor to use. * @param computation the computation which eventually yields the resulting value * @param <V> the type of the resulting value * @return a promise which will either be eventually supplied with the result of the computation or with an error */ public <V> Promise<V> fork(String category, final Supplier<V> computation) { final Promise<V> result = new Promise<>(); executor(category).dropOnOverload(() -> result.fail(new RejectedExecutionException())).fork(() -> { try { result.success(computation.get()); } catch (Exception t) { result.fail(t); } }); return result; }
private void executeTask(final TimedTask task) { tasks.executor(TIMER) .dropOnOverload(() -> Exceptions.handle() .to(LOG) .withSystemErrorMessage( "Dropping timer task '%s' (%s) due to system overload!", task, task.getClass()) .handle()) .start(() -> { try { Watch w = Watch.start(); task.runTimer(); if (w.elapsed(TimeUnit.SECONDS, false) > 1) { LOG.WARN("TimedTask '%s' (%s) took over a second to complete! " + "Consider executing the work in a separate executor!", task, task.getClass()); } } catch (Exception t) { Exceptions.handle(LOG, t); } }); }