JPPF Tasks and Execution Policy
From JPPFWiki
| Main Page > JPPF Tasks and Execution Policy |
What is an execution policy?
An execution policy is an object that determines whether a particular set of JPPF tasks can be executed on a JPPF node.
It does so by applying the set of rules (or tests) it is made of, against a set of properties associated with the node.
The properties of the node include:
- JPPF configuration properties
- System properties (including -D*=* properties specified on the JVM command line)
- Environment variables (e.g. PATH, JAVA_HOME, etc.)
- Networking: list of ipv4 and ipv6 addresses with corresponding host name when it can be resolved
- Runtime information such as maximum heap memory, number of available processors, etc...
The kind of tests that can be performed apply to the value of a property and include:
- Binary comparison operators: ==, <, <=, >, >= ; for instance: property_value <= 15
- Range operators (intervals): property_value in [a,b] , [a,b[ , ]a,b] , ]a,b[
- "One of" operator (discrete sets): property_value in { a1, ... , aN }
- "Contains string" operator: property_value contains "substring"
- Regular expressions: property_value matches "regexp"
- Custom, user-defined tests
The tests can also be combined into complex expressions using the boolean operators NOT, AND, OR and XOR.
Using this mechanism, it is possible to write an execution policy such as: "Execute on a node only if the node has at least 256 MB of memory and at least 2 CPUs available"
An execution policy is sent along with the tasks to the JPPF driver, and evaluated by the driver. They do not need to be sent to the nodes.
How do I use it?
Creating an execution policy
An execution policy is an object whose type is a subclass of ExecutionPolicy.
It can be built in 2 ways:
- by API, using the classes in the org.jppf.node.policy package.
Example:
// define a policy allowing only nodes with 2 processing threads or more
ExecutionPolicy atLeast2ThreadsPolicy = new AtLeast("processing.threads", 2);
// define a policy allowing only nodes that are part of the "mydomain.com"
// internet domain (case ignored)
ExecutionPolicy myDomainPolicy = new Contains("ipv4.addresses", true, "mydomain.com");
// define a policy that requires both of the above to be satisfied
ExecutionPolicy myPolicy = atLeast2ThreadsPolicy.and(myDomainPolicy);
Alternatively, this could be written in a single statement:
// define the same policy in one statement
ExecutionPolicy myPolicy = new AtLeast("processing.threads", 2).and(new Contains("ipv4.addresses", true, "mydomain.com"));
- using an XML policy document:
Example XML policy:
<ExecutionPolicy>
<!-- define a policy that requires both rules to be satisfied -->
<AND>
<!-- define a policy allowing only nodes with 2 processing threads or more -->
<AtLeast>
<Property>processing.threads</Property>
<Value>2</Value>
</AtLeast>
<!-- define a policy allowing only nodes that are part of the "mydomain.com"
internet domain (case ignored) -->
<Contains ignoreCase="true">
<Property>ipv4.addresses</Property>
<Value>mydomain.com</Value>
</Contains>
</AND>
</ExecutionPolicy>
As you can see, this is the exact equivalent of the policy we constructed programmatically before.
- To transform this XML policy into an ExecutionPolicy object, we will have to parse it using the PolicyParser API, by the means of one of the following methods:
static ExecutionPolicy parsePolicy(String) // parse from a string static ExecutionPolicy parsePolicyFile(String) // parse from a file static ExecutionPolicy parsePolicy(File) // parse from a file static ExecutionPolicy parsePolicy(Reader) // parse from a Reader static ExecutionPolicy parsePolicy(InputStream) // parse from an InputStream
Example use:
// parse the specified XML file into an ExecutionPolicy object
ExecutionPolicy myPolicy = PolicyParser.parsePolicy("../policies/MyPolicy.xml");
- It is also possible to validate an XML execution policy against the JPPF Execution Policy schema using one the the validatePolicy() methods of PolicyParser:
static ExecutionPolicy validatePolicy(String) // validate from a string static ExecutionPolicy validatePolicyFile(String) // validate from a file static ExecutionPolicy validatePolicy(File) // validate from a file static ExecutionPolicy validatePolicy(Reader) // validate from a Reader static ExecutionPolicy validatePolicy(InputStream) // validate from an InputStream
To enable validation, the document's namespace must be specified in the root element:
<jppf:ExecutionPolicy xmlns:jppf="http://www.jppf.org/schemas/ExecutionPolicy.xsd"> ... </jppf:ExecutionPolicy>
Example use:
public ExecutionPolicy createPolicy(String policyPath)
{
try
{
// validate the specified XML file
PolicyParser.validatePolicyFile(policyPath);
}
catch(Exception e)
{
// the validation and parsing errors are in the exception message
System.err.println("The execution policy " + policyPath +
" is not valid: " + e.getMessage());
return null;
}
// the policy is valid, we can parse it safely
return PolicyParser.parsePolicyFile(policyPath);
}
Applying an execution policy
Now that we have seen how to create an execution policy, it is finally time to use it with JPPF.
New methods have been added to the AbstractJPPFClient class:
submit(List<JPPFTask>, DataProvider, ExecutionPolicy) submitNonBlocking(List<JPPFTask>, DataProvider, TaskResultListener, ExecutionPolicy)
Example use:
// Initialize the JPPF client JPPFClient jppfClient = new JPPFClient(); // Create the tasks to submit to the JPPF grid List<JPPFTask> tasks = ...; // Create an eventual data provider DataProvider dataProvider = ...; // Create the execution policy to apply to the tasks ExecutionPolicy policy = createPolicy(); // Submit the tasks to the JPPF grid, along with the execution policy to apply List<JPPFTask> results = jppfClient.submit(tasks, dataProvider, policy);
Reference
Special case: using a custom policy class
It is possible to apply user-defined policies. When you do so, a number of constraints must be respected:
- the custom policy class must extend CustomPolicy
- the custom policy class must be deployed in the JPPF server classpath as well as the client's
Creating a custom policy class
Here is a sample custom policy code:
package my.package;
import org.jppf.management.JPPFSystemInformation;
import org.jppf.node.policy.CustomPolicy;
// define a policy allowing only nodes with 2 processing threads or more
public class MyCustomPolicy extends CustomPolicy
{
public boolean accepts(JPPFSystemInformation info)
{
// get the value of the "processing.threads" property
String s = this.getProperty(info, "processing.threads");
int n = -1;
try { n = Integer.valueOf(s); }
catch(NumberFormatException e) { // process the exception }
// node is accepted only if number of threads >= 2
return n >= 2;
}
}
Now, let's imagine that we want our policy to be more generic, and to accept nodes with at least a parametrized number of threads given as argument to the policy. Our accepts() method becomes then:
public boolean accepts(JPPFSystemInformation info)
{
// get the value to compare with, passed as the first argument to this policy
String s1 = getArgs()[0];
int param = -1;
try { param = Integer.valueOf(s1); }
catch(NumberFormatException e) { }
String s2 = getProperty(info, "processing.thread");
int n = -1;
try { n = Integer.valueOf(s2); }
catch(NumberFormatException e) { }
// node is accepted only if number of threads >= param
return n >= param;
}
Here we use the getArgs() method which returns an array of strings, corresponding to the arguments passed in the XML representation of the policy.
Using a custom policy in an XML policy document
Here is an example XML representation of the custom policy we created above:
<CustomRule class="my.package.MyCustomPolicy"> <Arg>3</Arg> </CustomRule>
The "class" attribute is the fully qualified name of the custom policy class.
There can be any number of <Arg> elements, these are the parameters that will then be accessible through CustomPolicy.getArgs().
When the XML descriptor is parsed, an execution policy object will be created in a way that is exactly equivalent to this code snippet:
MyCustomPolicy policy = new MyCustomPolicy(); policy.setArgs( "3" );
