@@ -0,0 +1,25 @@ | |||
package org.cobbzilla.util.daemon; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
public interface ExceptionHandler { | |||
void handle(Exception e); | |||
Logger log = LoggerFactory.getLogger(ExceptionHandler.class); | |||
ExceptionHandler DEFAULT_EX_RUNNABLE = e -> log.error("Error: " + e); | |||
static ExceptionHandler exceptionRunnable(Class<? extends Throwable>[] fatalExceptionClasses) { | |||
return e -> { | |||
for (Class<? extends Throwable> c : fatalExceptionClasses) { | |||
if (c.isAssignableFrom(e.getClass())) { | |||
if (e instanceof RuntimeException) throw (RuntimeException) e; | |||
ZillaRuntime.die("fatal exception: "+e); | |||
} | |||
} | |||
DEFAULT_EX_RUNNABLE.handle(e); | |||
}; | |||
} | |||
} |
@@ -31,6 +31,7 @@ import static java.util.concurrent.TimeUnit.SECONDS; | |||
import static java.util.stream.LongStream.range; | |||
import static org.apache.commons.collections.CollectionUtils.collect; | |||
import static org.apache.commons.lang3.exception.ExceptionUtils.getStackTrace; | |||
import static org.cobbzilla.util.daemon.ExceptionHandler.DEFAULT_EX_RUNNABLE; | |||
import static org.cobbzilla.util.io.FileUtil.abs; | |||
import static org.cobbzilla.util.io.FileUtil.list; | |||
import static org.cobbzilla.util.reflect.ReflectionUtil.instantiate; | |||
@@ -66,27 +67,9 @@ public class ZillaRuntime { | |||
public static boolean bool(Boolean b) { return b != null && b; } | |||
public static boolean bool(Boolean b, boolean val) { return b != null ? b : val; } | |||
public interface ExceptionRunnable { void handle(Exception e); } | |||
public static final ExceptionRunnable DEFAULT_EX_RUNNABLE = e -> { | |||
log.error("Error: " + e); | |||
}; | |||
public static ExceptionRunnable exceptionRunnable (Class<? extends Throwable>[] fatalExceptionClasses) { | |||
return e -> { | |||
for (Class<? extends Throwable> c : fatalExceptionClasses) { | |||
if (c.isAssignableFrom(e.getClass())) { | |||
if (e instanceof RuntimeException) throw (RuntimeException) e; | |||
die("fatal exception: "+e); | |||
} | |||
} | |||
DEFAULT_EX_RUNNABLE.handle(e); | |||
}; | |||
} | |||
public static Thread background (Runnable r) { return background(r, DEFAULT_EX_RUNNABLE); } | |||
public static Thread background (Runnable r, ExceptionRunnable ex) { | |||
public static Thread background (Runnable r, ExceptionHandler ex) { | |||
final Thread t = new Thread(() -> { | |||
try { | |||
r.run(); | |||
@@ -124,7 +107,7 @@ public class ZillaRuntime { | |||
public static <T> T retry (Callable<T> func, | |||
int tries, | |||
Function<Integer, Long> backoff, | |||
ExceptionRunnable ex) { | |||
ExceptionHandler ex) { | |||
Exception lastEx = null; | |||
try { | |||
for (int i = 0; i < tries; i++) { | |||
@@ -1,8 +1,10 @@ | |||
package org.cobbzilla.util.main; | |||
import lombok.AccessLevel; | |||
import lombok.AllArgsConstructor; | |||
import lombok.Getter; | |||
import lombok.extern.slf4j.Slf4j; | |||
import org.cobbzilla.util.daemon.ExceptionHandler; | |||
import org.cobbzilla.util.daemon.ZillaRuntime; | |||
import org.kohsuke.args4j.CmdLineException; | |||
import org.kohsuke.args4j.CmdLineParser; | |||
@@ -22,18 +24,6 @@ public abstract class BaseMain<OPT extends BaseMainOptions> { | |||
protected abstract void run() throws Exception; | |||
public void runOrDie () { try { run(); } catch (Exception e) { die("runOrDie: "+e, e); } } | |||
public void runOrDie (ZillaRuntime.ExceptionRunnable errorHandler) { | |||
try { run(); } catch (Exception e) { errorHandler.handle(e); } | |||
} | |||
public Thread runInBackground () { return background(this::runOrDie); } | |||
public Thread runInBackground (ZillaRuntime.ExceptionRunnable errorHandler) { | |||
return background(() -> runOrDie(errorHandler)); | |||
} | |||
@Getter private String[] args; | |||
public void setArgs(String[] args) throws CmdLineException { | |||
this.args = args; | |||
@@ -116,4 +106,21 @@ public abstract class BaseMain<OPT extends BaseMainOptions> { | |||
System.exit(1); | |||
return null; | |||
} | |||
public Thread runInBackground (ExceptionHandler errorHandler) { | |||
return background(new RunWithHandler(this, errorHandler), errorHandler); | |||
} | |||
@AllArgsConstructor | |||
private static class RunWithHandler implements Runnable { | |||
private final BaseMain runnable; | |||
private final ExceptionHandler errorHandler; | |||
@Override public void run() { | |||
try { | |||
runnable.run(); | |||
} catch (Exception e) { | |||
errorHandler.handle(e); | |||
} | |||
} | |||
} | |||
} |