Hello,
Yes, a task can decide that it failed and act accordingly. JPPF does not provide any API to cancel a single task, however it is possible to cancel the job currently executing in the node.
This requires a custom implementation of a
node life cycle listener. Here is a simple example:
import org.jppf.management.JMXNodeConnectionWrapper;
import org.jppf.node.event.*;
// Simple node listener implementation that enables tasks
// to cancel the current job while executing in the node.
public class SelfCancelNodeListener implements NodeLifeCycleListener {
// holds the uuid of the job being executed.
private static String currentJobUuid = null;
@Override
public void jobStarting(final NodeLifeCycleEvent event)
{
SelfCancelNodeListener.setCurrentJobUuid(event.getJob().getUuid());
}
@Override
public void jobEnding(final NodeLifeCycleEvent event)
{
// reset the uuid
SelfCancelNodeListener.setCurrentJobUuid(null);
}
// get the uuid of the job being executed.
public static synchronized String getCurrentJobUuid() {
return currentJobUuid;
}
// set the uuid of the job being executed.
public static synchronized void setCurrentJobUuid(final String currentJobUuid) {
SelfCancelNodeListener.currentJobUuid = currentJobUuid;
}
// cancel the job. "resubmit = true" means the job should be resubmitted to another node.
public static void cancelCurrentJob(final boolean resubmit) {
String uuid = getCurrentJobUuid();
if (uuid != null) {
// no-args contructor implies connection to local (same JVM) JMX server
JMXNodeConnectionWrapper nodeJmx = new JMXNodeConnectionWrapper();
nodeJmx.connect();
try {
nodeJmx.cancelJob(uuid, resubmit);
} catch (Exception e) {
System.out.println("error while attempting to cancel job with uuid=" + uuid);
e.printStackTrace();
}
}
}
@Override
public void nodeStarting(final NodeLifeCycleEvent event) {
}
@Override
public void nodeEnding(final NodeLifeCycleEvent event) {
}
}Here, we can see that we need the NodeLifeCycleListener implementation so we can gain access to the job uuid, in order to cancel it. Also note the use of the boolean flag in JMXNodeConnectionWrapper.cancelJob(), to indicate whether the job should be resubmitted by the driver.
In your tasks this could be used as follows:
import org.jppf.server.protocol.JPPFTask;
// A simple task that may cancel the current job while executing in the node.
public class SelfCancelTask extends JPPFTask {
@Override
public void run() {
// ... some code here ...
// cancel the job and specify that we want the driver to resubmit it to another node
SelfCancelNodeListener.cancelCurrentJob(true);
}
@Override
public void onCancel() {
System.out.println("this task has been cancelled");
}
}I hope this helps.
Sincerely,
-Laurent