/** {@inheritDoc} */ public void run() { logger.log(Level.FINE, "Starting a consumer for transactions"); notifyThreadJoining(); try { while (true) { // wait for the next task, at which point we may get // interrupted and should therefore return ScheduledTaskImpl task = (ScheduledTaskImpl) (backingQueue.getNextTask(true)); // run the task, checking if it completed if (executeTask(task, false, true)) { // if it's a recurring task, schedule the next run if (task.isRecurring()) { long nextStart = task.getStartTime() + task.getPeriod(); task = new ScheduledTaskImpl(task, nextStart); backingQueue.addTask(task); } // if it has dependent tasks, schedule the next one TaskQueueImpl queue = (TaskQueueImpl) (task.getTaskQueue()); if (queue != null) { queue.scheduleNextTask(); } } } } catch (InterruptedException ie) { if (logger.isLoggable(Level.FINE)) { logger.logThrow(Level.FINE, ie, "Consumer is finishing"); } } catch (Exception e) { // this should never happen, since running the task should // never throw an exception that isn't handled logger.logThrow(Level.SEVERE, e, "Fatal error for consumer"); } finally { notifyThreadLeaving(); } }