The other day I was implementing an important service in my application, that should continue to run no matter what. So I used the following construct:
ScheduledExecutorService ses =
Executors.newSingleThreadScheduledExecutor();
//If the thread dies, another will take over
ses.scheduleAtFixedRate(importantPeriodicTask, 1, 1, TimeUnit.NANOSECONDS);
...only to find out that when importantPeriodicTask acutually throws a RuntimeException or Error, the ScheduledExecutorService
will stop executing this task (they will cease to be scheduled).
This is of course exactly what the javadoc says:
If any execution of the task encounters an exception, subsequent executions are suppressed.
So shame on me, but I couldn't understand why the authors implemented ScheduledExecutorService
like this.
Granted, a RuntimeException or Error should generally not be caught, especially Error. But in reality, especially in case of RuntimeException, truth is that they are thrown quite common in production deployment, and I feel it is almost always desirable that while that particular operation should fail, the app itself should not fail because of that isolated error.
It is true that a suppression of one periodic task does not affect other kinds of periodic tasks. But given the nature of most periodic tasks, shouldn't these tasks perceived as a "service", rather than isolated tasks?
In other words, shouldn't only that one instance of importantPeriodicTask
fail, and the task itself be continued to be rescheduled?