package edu.washington.escience.myria.util.concurrent;
import java.util.TimerTask;
import java.util.concurrent.ScheduledExecutorService;
import edu.washington.escience.myria.util.JVMUtils;
/**
* The Java {@link ScheduledExecutorService} suppress the subsequent execution of a {@link TimerTask} if any execution
* of the task encounters an exception. This class captures all {@link Throwable}s and logs them. And all
* {@link Exception}s are ignored but all {@link Error}s are re-thrown. In this way, the execution of the
* {@link TimerTask}s will only get stopped by explicit cancel or shutdown.
* */
public abstract class ErrorLoggingTimerTask extends TimerTask {
/** The logger for this class. */
private static final org.slf4j.Logger LOGGER =
org.slf4j.LoggerFactory.getLogger(ErrorLoggingTimerTask.class.getName());
/**
* Process error.
*
* @param t the error.
* */
protected void exceptionCaught(final Throwable t) {
if (LOGGER.isErrorEnabled()) {
LOGGER.error("Exception in TimerTask: ", t);
}
}
@Override
public final void run() {
try {
runInner();
} catch (Throwable e) {
exceptionCaught(e);
if (e instanceof InterruptedException) {
Thread.currentThread().interrupt();
} else if (e instanceof Error) {
if (e instanceof OutOfMemoryError) {
JVMUtils.shutdownVM(e);
}
throw (Error) e;
} else if (e instanceof RuntimeException) {
throw (RuntimeException) e;
}
}
}
/**
* actual run code.
*
* @throws Exception if any error occurs.
* */
protected abstract void runInner() throws Exception;
}