/** * Add a start lifecycle event, useful for initialize and/or start services at startup time. * * You should ONLY call this method while the application is been initialized or from * {@link Jooby.Module#configure(Env, Config, com.google.inject.Binder)}. * * The behavior of this method once application has been initialized is <code>undefined</code>. * * @param task Task to run. * @return This env. */ @Nonnull default LifeCycle onStart(final Throwing.Runnable task) { return onStart(app -> task.run()); }
/** * Creates a side effect try from given runnable. Don't forget to either throw or log the exception * in case of failure. Unless, of course you don't care about the exception. * * Log the exception: * <pre>{@code * Try.run(() -> ...) * .onFailure(x -> x.printStacktrace()); * }</pre> * * Throw the exception: * <pre>{@code * Try.run(() -> ...) * .throwException(); * }</pre> * * @param runnable Runnable. * @return A void try. */ public static Try run(Throwing.Runnable runnable) { try { runnable.run(); return new Success<>(null); } catch (Throwable x) { return new Failure(x); } }
/** * Add a started lifecycle event. Started callbacks are executed when the application is ready: * modules and servers has been started. * * You should ONLY call this method while the application is been initialized or while * {@link Jooby.Module#configure(Env, Config, com.google.inject.Binder)}. * * The behavior of this method once application has been initialized is <code>undefined</code>. * * @param task Task to run. * @return This env. */ @Nonnull default LifeCycle onStarted(final Throwing.Runnable task) { return onStarted(app -> task.run()); }
/** * Add a stop lifecycle event, useful for cleanup and/or stop service at stop time. * * You should ONLY call this method while the application is been initialized or from * {@link Jooby.Module#configure(Env, Config, com.google.inject.Binder)}. * * The behavior of this method once application has been initialized is <code>undefined</code>. * * @param task Task to run. * @return This env. */ @Nonnull default LifeCycle onStop(final Throwing.Runnable task) { return onStop(app -> task.run()); }
private static <X extends Throwable> void runUnwrap(Runnable action, Class<? extends X> type) { try { action.tryRun(); } catch (Throwable x) { if (isFatal(x)) { throw sneakyThrow(x); } Throwable t = x; if (type.isInstance(x)) { t = Optional.ofNullable(x.getCause()).orElse(x); } throw sneakyThrow(t); } }
/** * Always run the given action, works like a finally clause. * * @param action Finally action. * @return This try result. */ public Try onComplete(Throwing.Runnable action) { try { action.run(); return this; } catch (Throwable x) { return Try.failure(x); } }
/** * Add a start lifecycle event, useful for initialize and/or start services at startup time. * * You should ONLY call this method while the application is been initialized or from * {@link Jooby.Module#configure(Env, Config, com.google.inject.Binder)}. * * The behavior of this method once application has been initialized is <code>undefined</code>. * * @param task Task to run. * @return This env. */ @Nonnull default LifeCycle onStart(final Throwing.Runnable task) { return onStart(app -> task.run()); }
private static <X extends Throwable> void runOnFailure(Runnable action, Class<? extends X> type, java.util.function.Consumer<X> consumer) { try { action.tryRun(); } catch (Throwable x) { if (type.isInstance(x)) { consumer.accept(type.cast(x)); } throw sneakyThrow(x); } }
/** * Wrap an exception as new exception provided by the given wrap function. * * @param wrapper Wrap function. * @return A new consumer. */ default Runnable wrap(java.util.function.Function<Throwable, Exception> wrapper) { return () -> runWrap(() -> tryRun(), wrapper); }
/** * Execute the given action before throwing the exception. * * @param action Action to execute. * @return A new consumer with a listener action. */ default Runnable onFailure(java.util.function.Consumer<Throwable> action) { return onFailure(Throwable.class, action); }
private static void runWrap(Runnable action, java.util.function.Function<Throwable, Exception> wrapper) { try { action.tryRun(); } catch (Throwable x) { if (isFatal(x)) { throw sneakyThrow(x); } throw sneakyThrow(wrapper.apply(x)); } }
/** * Unwrap an exception and rethrow. Useful to produce clean/shorter stacktraces. * * @param type Type to unwrap. * @param <X> Exception type. * @return A new consumer. */ default <X extends Throwable> Runnable unwrap(Class<? extends X> type) { return () -> runUnwrap(() -> tryRun(), type); } }
private Throwing.Runnable sync(final Throwing.Runnable task) { return () -> { synchronized (this) { task.run(); } }; }
/** * Execute the given action before throwing the exception. * * @param type Exception type filter. * @param action Action to execute. * @param <X> Exception type. * @return A new consumer with a listener action. */ default <X extends Throwable> Runnable onFailure(Class<? extends X> type, java.util.function.Consumer<X> action) { return () -> runOnFailure(() -> tryRun(), type, action); }
private static void runAction(Runnable action) { try { action.tryRun(); } catch (Throwable x) { throw sneakyThrow(x); } }
/** * Add a started lifecycle event. Started callbacks are executed when the application is ready: * modules and servers has been started. * * You should ONLY call this method while the application is been initialized or while * {@link Jooby.Module#configure(Env, Config, com.google.inject.Binder)}. * * The behavior of this method once application has been initialized is <code>undefined</code>. * * @param task Task to run. * @return This env. */ @Nonnull default LifeCycle onStarted(final Throwing.Runnable task) { return onStarted(app -> task.run()); }
/** * Add a stop lifecycle event, useful for cleanup and/or stop service at stop time. * * You should ONLY call this method while the application is been initialized or from * {@link Jooby.Module#configure(Env, Config, com.google.inject.Binder)}. * * The behavior of this method once application has been initialized is <code>undefined</code>. * * @param task Task to run. * @return This env. */ @Nonnull default LifeCycle onStop(final Throwing.Runnable task) { return onStop(app -> task.run()); }
private Throwing.Runnable sync(final Throwing.Runnable task) { return () -> { synchronized (this) { task.run(); } }; }