Performing custom actions at when cancelling a workflow

I'm currently working with a few custom Knime nodes that interact with a separate Hadoop cluster, when cancelling a Knime workflow i basically want to be able to tell the cluster to kill the jobs it started. Is there any mechanism in Knime to trigger certain java code upon cancellation of the workflow ?

In your execute method you can do something like this:

 

         try
            {
                exec.checkCanceled();
            } catch (Throwable e)
            {
                System.out.println("We can now do some stuff");
                
                throw e;
            }

 

or maybe this would be better code:

 

try
{
        exec.checkCanceled();
} catch (CanceledExecutionException e)
{
        System.out.println("We can now do some stuff");
        throw e;
}

 

Catch the Throwable that exec.checkCanceled() throws, do your hadoop based stuff and then rethrow. 

Thanks, this is EXACTLY whan i was looking for!

Didn't think to look through the execution context, d'oh

So I've been playing around with this a bit and i noticed that you're only given a limited amount of time to run your cleanup code until execution is terminated. Unfortunately, not long enough time to make a rest call to the cluster to terminate the jobs.

So if i call a function that takes, say, more than 1 second in that catch block it wouldn't get properly executed before termination. Am i correct in assuming this is indeed a time limit, and if so, is this something configurable from Knime ?

No, there is not time limit. A node has to finish execution by itself when it's canceled. However, the thread in which the node executed is interrupted. This may cause e.g. I/O functions to return immediately unless the interrupted flag is cleared.

    protected BufferedDataTable[] execute(final BufferedDataTable[] inData,
            final ExecutionContext exec) throws Exception {
        :
        for (...) {
            Thread.sleep(5000);
            :
            try
            {
                exec.checkCanceled();
            } catch (CanceledExecutionException e)
            {
                // CLEAN UP!
                throw e;
            }
        }
    }

I'm not sure if I understand it correctly; also referring to https://tech.knime.org/forum/knime-developers/reacting-on-cancellation-events#comment-33646

I have a loop inside the execute method.  If the cancel request comes in some long lasting i/o operation (represented by "Thread.sleep()" in my example), then an exception will be thrown in this operation, and I have to additionally catch exceptions from these calls as well if I want to do some cleanup, am I right?

In other words, checkCanceled() is only intended for long "own" computations that don't do such i/o calls?

Frank

So in reverse this means that there is no need to call checkCanceled() as long as there are such i/o functions that are called "often enough" in each loop iteration, correct?

All correct. You need to catch InterruptedExceptions in this case.