@Override public synchronized void handleEvent(Event event) { JobRunner runner = (JobRunner) event.getRunner(); if (event.getType() == Type.JOB_STATUS_CHANGED) { updateFlow(); } else if (event.getType() == Type.JOB_FINISHED) { ExecutableNode node = runner.getNode(); long seconds = (node.getEndTime() - node.getStartTime()) / 1000; synchronized (mainSyncObj) { logger.info( "Job " + node.getNestedId() + " finished with status " + node.getStatus() + " in " + seconds + " seconds"); // Cancellation is handled in the main thread, but if the flow is // paused, the main thread is paused too. // This unpauses the flow for cancellation. if (flowPaused && node.getStatus() == Status.FAILED && failureAction == FailureAction.CANCEL_ALL) { flowPaused = false; } finishedNodes.add(node); node.getParentFlow().setUpdateTime(System.currentTimeMillis()); interrupt(); fireEventListeners(event); } } }