Wednesday, February 2, 2011

Get Notified When Your Periodic Task Throws an Exception

I've written up a how-to on a periodic task with a watchdog; now I want to handle exceptions and notify interested observers when exceptions occur. The watchdog is in place in case exceptions don't get handled at all, in which case subsequent executions of the scheduled thread will be suppressed. in this case, the watchdog knows that some problem occurred - but it doesn't know just what that was. As an alternative (or in addition) to the watchdog, we simply catch exceptions in the Runnable passed to our Executor, handling it by both logging the information and notifying interested listeners. This helps pass along exception information from a different stack of execution, since the problem occurs in a different thread:


private class TheTask implements Runnable {
public void run() {
try {
// do stuff on each execution, catching exceptions
} catch (Throwable t) {
log.error("Problem with custom group-by retrieval: ", e);
notifyListeners(e);
}
}
}
}

The call to notify listeners comes from additions to the superclass PeriodicTask (see previous article):


private Queue<PeriodicTaskListener> listeners = new LinkedList<PeriodicTaskListener>();

/**
* Add a listener to be notified of events of interest
*/
public void addListener(PeriodicTaskListener theListener) {
listeners.add(theListener);
}

/**
* Notify all listeners that an exception occurred
*/
protected void notifyListeners(Throwable t) {
for (PeriodicTaskListener listener : listeners) {
listener.exceptionHandled(t);
}
}

The interested observer needs to implement the listener interface:


public interface PeriodicTaskListener {

void exceptionHandled(Throwable t);
}

..............

@Override
public void exceptionHandled(Throwable t) {
// do what's needed here
}

...plus it needs a handle to the Poller to register itself:


PeriodicTask poller = watchdog.getTask();
poller.addListener(this);

If there's no watchdog in play, we can get the poller reference from the Spring context, e.g. In either event - we now are handling/logging exceptions, so the task will not have subsequent executions suppressed in the face of an exception; plus, we now can have clients and interested observers of the task get called back whenever an exception occurs.

No comments:

Post a Comment