JPPF Forums

General Discussions => Forums => Topic started by: abuouf on August 08, 2012, 11:52:07 AM

Title: How cancel job from task, and how to send the result from task to client
Post by: abuouf on August 08, 2012, 11:52:07 AM
hi dears,
i have two problem with jppf
1- How cancel job from task
jppfClient.cancelJob(jobId);
doesn't work
2-how to send the result from task to client
thanks
Title: Re: How cancel job from task, and how to send the result from task to client
Post by: lolo on August 10, 2012, 06:43:48 AM
Hello,

I'm assuming that you want to cancel the entire job from an executing task, including the tasks that are executing on other nodes, is this correct?
If yes, then the task will need to know about 2 pieces of information:
- the uuid of the job to cancel
- the host and port of the JMX server for the driver to which the node is attached

Since the task doesn't know about the job it is part of, you will need a way to access information about that job.
This can be done using a node life cycle listener (http://www.jppf.org/doc/v3/index.php?title=Receiving_notifications_of_node_life_cycle_events) addon as follows:

Code: [Select]
package test;
import org.jppf.management.JMXDriverConnectionWrapper;
import org.jppf.node.event.*;

public class MyNodeListener implements NodeLifeCycleListener {

  // singleton instance for easy access from the tasks
  private static MyNodeListener instance;
  // uuid of the current job being executed, if any
  private String currentUuid = null;
  // connection to the driver's connection wrapper
  private JMXDriverConnectionWrapper driverJmx = null;

  public static MyNodeListener getInstance() {
    return instance;
  }

  // the node should only create one instance of this listener
  public MyNodeListener() {
    instance = this;
  }

  @Override
  public void jobStarting(final NodeLifeCycleEvent event) {
    // store the uuid before the job starts in the node
    currentUuid = event.getJob().getUuid();
  }

  @Override
  public void jobEnding(final NodeLifeCycleEvent event) {
    // reset the job uuid
    currentUuid = null;
  }

  @Override
  public void nodeStarting(final NodeLifeCycleEvent event) {
    // establish a connection to the driver's JMX server
    String host = "driverHost";
    int port = 11198; // use the proper port number here
    driverJmx = new JMXDriverConnectionWrapper(host, port, false);
    driverJmx.connect();
  }

  @Override
  public void nodeEnding(final NodeLifeCycleEvent event) {
    if ((driverJmx != null) && driverJmx.isConnected()) {
      try {
        driverJmx.close();
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
  }

  // cancel the current job, if any is running
  public void cancelJob() {
    if ((currentUuid != null) && driverJmx.isConnected()) {
      try {
        driverJmx.cancelJob(currentUuid);
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
  }
}

From the task you can then use a ClientDataProvider (http://www.jppf.org/doc/v3/index.php?title=Sharing_data_among_tasks_:_the_DataProvider_API#ClientDataProvider:_computing_data_in_the_client) to execute some code in the client JVM, so as to store the results of a task for instance:

Code: [Select]
package test;
import org.jppf.server.protocol.JPPFTask;
import org.jppf.task.storage.ClientDataProvider;
import org.jppf.utils.JPPFCallable;

public class MyTask extends JPPFTask {
  @Override
  public void run() {
    // ... some code ...

    // execute some code on the client side via the ClientDataProvider
    ClientDataProvider dataProvider = (ClientDataProvider) getDataProvider();
    dataProvider.computeValue("computeResult", new MyCallable(this));
    // we can now cancel the job
    MyNodeListener.getInstance().cancelJob();
  }

  public static class MyCallable implements JPPFCallable<String> {
    private MyTask task;

    public MyCallable(MyTask task) {
      this.task = task;
    }

    // this method will be executed on the client side
    @Override
    public String call() throws Exception
    {
      try {
        // ... your code here ...
      } catch (Exception e) {
        return e.getMessage();
      }
      return "callable was successfully executed on the client side";
    }
  }
}

I hope this helps.

Sincerely,
-Laurent