@Override public final void invoke() throws Exception { LOG.debug("Invoking {}", getName()); boolean disposed = false; try { // first order of business is to ive operators back their state restoreStateLazy(); // we need to make sure that any triggers scheduled in open() cannot be // executed before all operators are opened synchronized (lock) { openAllOperators(); } // let the task do its work isRunning = true; run(); isRunning = false; if (LOG.isDebugEnabled()) { LOG.debug("Finished task {}", getName()); } // make sure no further checkpoint and notification actions happen. // we make sure that no other thread is currently in the locked scope before // we close the operators by trying to acquire the checkpoint scope lock // we also need to make sure that no triggers fire concurrently with the close logic synchronized (lock) { // this is part of the main logic, so if this fails, the task is considered failed closeAllOperators(); } // make sure all buffered data is flushed operatorChain.flushOutputs(); // make an attempt to dispose the operators such that failures in the dispose call // still let the computation fail tryDisposeAllOperators(); disposed = true; } finally { isRunning = false; timerService.shutdownNow(); // release the output resources. this method should never fail. if (operatorChain != null) { operatorChain.releaseOutputs(); } // we must! perform this cleanup try { cleanup(); } catch (Throwable t) { // catch and log the exception to not replace the original exception LOG.error("Error during cleanup of stream task."); } // if the operators were not disposed before, do a hard dispose if (!disposed) { disposeAllOperators(); } try { if (stateBackend != null) { stateBackend.close(); } } catch (Throwable t) { LOG.error("Error while closing the state backend", t); } } }