Hello,
One thing that will help you is the ability to set the
maximum number of nodes a JPPF job (I believe that's what you mean by "task", is this correct?) can execute on
at any given time. This is an attribute of the job SLA, which is set as follows:
JPPFJob job = new JPPFJob();
job.setMaxNodes(2);
Then, there remains the problem of multiple tasks (in JPPF terminology: instances of AbstractTask) being dispatched to each job, which may be executing concurrently in each node.
There are multiple ways to handle this:
1) you may already handle this in your tasks, soemhow sequentializing access to the licensed service or library
2) you could unconditionally configure each node with a single processing thread - this would however, limit the performance of all jobs, including those that don't have licensing constraints
3) you could dynamically update the number of processing threads, for instance from a
NodeLifeCycleListener and based on
job metadata, as in this example:
import org.jppf.management.JMXNodeConnectionWrapper;
import org.jppf.node.event.*;
// sets the number of processing threads based on job metadata
public class MyNodeListener extends NodeLifeCycleListenerAdapter {
private static final String LICENSING_PARAM = "has.license.constraint";
private int maxThreads = 0;
@Override
public void jobStarting(NodeLifeCycleEvent event) {
if (event.getJob().getMetadata().getParameter(LICENSING_PARAM, false)) {
setConstraintState(true);
}
}
@Override
public void jobEnding(NodeLifeCycleEvent event) {
if (event.getJob().getMetadata().getParameter(LICENSING_PARAM, false)) {
setConstraintState(false);
}
}
private void setConstraintState(boolean active) {
// obtain a local node management wrapper object
JMXNodeConnectionWrapper jmx = new JMXNodeConnectionWrapper();
jmx.connect();
try {
if (active) {
// set the max num of executing threads
this.maxThreads = jmx.state().getThreadPoolSize();
jmx.updateThreadPoolSize(1);
} else {
// restore the max num of executing threads
jmx.updateThreadPoolSize(this.maxThreads);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
4) you can also set the server's load balancing configuration to a fixed size of 1, with basically the same performance impact as 2) :
jppf.load.balancing.algorithm = manual
jppf.load.balancing.profile = test
jppf.load.balancing.profile.test.size = 1
5) You could use a
custom load-balancer that would have
access to the job and would send only one task to the node when the job has licensing constraints. This is probably the most complex option to implement.
I guess that's a nice array of options we have here

Sincerely,
-Laurent
PS: I think this topic would be a better fit in the "Developers help" forum. If you're ok with this, I will move it there.