Driver management and monitoring
From JPPF 6.2 Documentation
|
Main Page > Management and monitoring > Driver management |
1 Node selectors
A large number of the driver management operations make use of node selectors to conveniently specify which nodes they apply to. A node selector represents a dynamic set of nodes that match one or more specified criteria or predicates. It is dynamic in nature because it accounts for nodes joining or leaving the JPPF grid at any time, and some of these nodes may match the node selector criteria.
Each node selector is an instance of the NodeSelector interface, defined as follows:
public interface NodeSelector extends Serializable { // Constant for a selector which accepts all nodes NodeSelector ALL_NODES = new AllNodesSelector(); // Determine whether the node is accepted boolean accepts(JPPFManagementInfo nodeInfo); }
The participation of a node is determined by the accepts() method, which takes a JPPFManagementInfo argument that represents information on the node as seen by the server. In particular, it provides access to the same node-specific JPPFSystemInformation object that is used by execution policies.
1.1 Selecting all the nodes
AllNodesSelector will select all the nodes currently attached to the driver. Rather than creating instances of this class, you can also use the predefined constant NodeSelector.ALL_NODES. This class is defined as:
// Selects all nodes public class AllNodesSelector implements NodeSelector { // Default constructor public AllNodesSelector() }
Example usage:
// these two selectors are equivalent NodeSelector selector1 = new AllNodesSelector(); NodeSelector selector2 = NodeSelector.ALL_NODES;
1.2 Execution policy selector
ExecutionPolicySelector uses an execution policy, such as can be set upon a JPPF job's SLA, to perform the selection of the nodes. It is defined as follows
// Selects nodes based on an execution policy public class ExecutionPolicySelector implements NodeSelector { // Initialize this selector with an execution policy public ExecutionPolicySelector(ExecutionPolicy policy) // Get the execution policy to use to select the nodes public ExecutionPolicy getPolicy() }
Example usage:
// define a selector that selects all nodes with at least 4 cores ExecutionPolicy policy = new AtLeast("availableProcessors", 4); NodeSelector selector = new ExecutionPolicySelector(policy);
1.3 UUID selector
UuidSelector will only select nodes whose UUID is part of the collection or array of specified UUIDs. It is defined as:
// Selects nodes based on their uuids public class UuidSelector implements NodeSelector { // Initialize this selector with a collection of node UUIDs public UuidSelector(Collection<String> uuids) // Initialize this selector with an array of node UUIDs public UuidSelector(String...uuids) // Get the collection of uuids of the nodes to select public Collection<String> getUuidList() }
Example usage:
// define a selector that selects all idle nodes at a given time JMXDriverConnectionWrapper driver = ...; // get the uuids of all idle nodes Collection<JPPFManagementInfo> infos = driver.idleNodesInformation(); List<String> uuids = new ArrayList<>(); if (infos ! null) { for (JPPFManagementInfo info: infos) uuids.add(info.getUuid()); } NodeSelector selector = new UuidSelector(uuids);
1.4 Scripted node selector
A ScriptedNodeSelector uses a script expression that evaluates to a boolean to determine which nodes are accepted. The script language must be accepted by the JVM and must conform to the JSR-223 / javax.script API specifications.
A scripted node selector is particularly useful when you need to implement a complex filtering logic but do not want to deploy the associated code in the driver's classpath.
ScriptedNodeSelector extends BaseScriptEvaluator and is defined as follows:
public class ScriptedNodeSelector extends BaseScriptEvaluator implements NodeSelector { // Initialize this selector with the specfied language and script public ScriptedNodeSelector(String language, String script) // Initialize this selector with the specfied language and script reader public ScriptedNodeSelector(String language, Reader scriptReader) throws IOException // Initialize this selector with the specfied language and script file public ScriptedNodeSelector(String language, File scriptFile) throws IOException }
The script will be evaluated for each JPPFManagementInfo passed as input to the accepts() method of the selector. The node information can be accessed from the script using a predefined variable name "nodeInfo", as in this example:
JPPFDriverAdminMBean driverAdmin = ...; NodeSelector selector; // create a selector with a Javascript script which accepts only master nodes selector = new ScriptedNodeSelector("javascript", "nodeInfo.isMasterNode();"); // or an equivalent Groovy script selector = new ScriptedNodeSelector("groovy", "return nodeInfo.isMasterNode()"); // get the number of selected nodes int nbMasterNodes = driverAdmin.nbNodes(selector);
1.5 Custom node selector
When a node selector requires a complex logic and its performance is critical, you can always write your own implementation of NodeSelector, as in this example:
public class CustomNodeSelector implements NodeSelector { @Override public boolean accepts(JPPFManagementInfo nodeInfo) { // retrieve the node's number of cores int n = nodeInfo.getSystemInformation().getRuntime().getInt("availableProcessors"); // accept only slave nodes with at least 4 cores return nodeInfo.isSlaveNode() && (n >= 4); } }
2 Driver state
The management and monitoring of a JPPF driver is performed via the JPPFDriverAdminMBean interface. This interface, which is also implemented by the JMXDriverConnectionWrapper class, provides ways to manage a driver's life cycle, update its configuration, as well as explore the nodes that are attached to it.
2.1 Stopping and restarting the driver
JPPFDriverAdminMBean has a single method to perform a driver shutdown, optionally followed by a restart:
public interface JPPFDriverAdminMBean extends JPPFAdminMBean { // Perform a shutdown or restart of the server. The server stops after // the specified shutdown delay, and restarts after the specified restart delay public String restartShutdown(Long shutdownDelay, Long restartDelay) throws Exception; }
Where:
- shutdownDelay represents how long, in milliseconds, to wait for the driver shutdown to be initiated. A value of zero or less means an immediate shutdown.
- restartDelay represents how long, in milliseconds, to wait before restarting the driver once the shutdown is complete. A negative value means that no restart is performed and the driver process just exits.
Please note that, once the shutdown operation is complete any connection to the driver"s JMX server will be invalidated and will no longer work. This includes instances of JMXDriverConnectionWrapper and any MBean proxy obtained from them. The connection will then have to be re-established, once the driver is restarted, either automaitcally or manually.
The following example schedules a driver shutdown after 30 seconds, then a restart 60 seconds after that:
// implicitely close the JMX connection try (JMXDriverConnectionWrapper driver = new JMXDriverConnectionWrapper("mydriver.org", 11111)) { driver.connectAndWait(5000L); // schedule a shutdown followed by a restart String ack = driver.restartShutdown(30_000L, 60_000L); System.out.println("acknowledgement: " + ack); }
2.2 Server statistics
You can get a snapshot of the server's state by invoking the following method, which provides statistics on execution performance, network overhead, server queue behavior, number of connected nodes and clients:
public interface JPPFDriverAdminMBean extends JPPFAdminMBean { // Get the latest statistics snapshot from the JPPF driver public JPPFStatistics statistics() throws Exception; }
This method returns an object of type JPPFStatistics. We invite you to read the section dedicated to the statistics API for the full details of its usage.
Additionally, you can reset the server statistics using the following method:
public interface JPPFDriverAdminMBean extends JPPFAdminMBean { // Reset the JPPF driver statistics public void resetStatistics() throws Exception; }
Example usage:
try (JMXDriverConnectionWrapper driver = ...) { driver.connectAndWait(5000L); JPPFStatistics stats = driver.statistics(); System.out.println( "submitted jobs: " + stats.getSnapshot(JPPFStatisticsHelper.JOB_TOTAL).getTotal()); }
2.3 Load-balancing settings
The driver management MBean provides the ability to dynamically obtain the server's load balancing settings:
public interface JPPFDriverAdminMBean extends JPPFAdminMBean { // Obtain the current load-balancing settings. public LoadBalancingInformation loadBalancerInformation() throws Exception; }
This method returns an object of type LoadBalancingInformation, defined as follows:
public class LoadBalancingInformation implements Serializable { // Get the name of the algorithm public String getAlgorithm() // Get the algorithm's parameters public TypedProperties getParameters() // Get the names of all available algorithms public List<String> getAlgorithmNames() }
- the value of algorithm is included in the list of algorithm names
- parameters contains a mapping of the algorithm parameters names to their current value. Unlike what we have seen in the configuration guide chapter, the parameter names are expressed without suffix. This means that instead of strategy.<profile_name>.<parameter_name>, they will just be named <parameter_name>.
It is also possible to dynamically change the load-balancing algorithm used by the server, and / or its parameters:
public interface JPPFDriverAdminMBean extends JPPFAdminMBean { // Change the load-balancing settings. public String changeLoadBalancerSettings(String algorithm, Map parameters) throws Exception; }
Where:
- algorithm is the name of the algorithm to use. If it is not known to the server, no change occurs.
- parameters is a map of algorithm parameter names to their value. Similarly to what we saw above, the parameter names must be expressed without suffix. Internally, the JPPF server will use the profile name “jppf”.
Here is an example usage:
JMXDriverConnectionWrapper driver = ...; // get the current load balancer settings LoadBalancingInformation lbi = driver.loadBalancerInformation(); try { // set to the "manual" algorithm with a size of 10 tasks per node driver.changeLoadBalancerSettings("manual", new TypedProperties().setInt("size", 10)); // ... submit some jobs with the new load balancer settings ... } finally { // restore the previous load balancer settings driver.changeLoadBalancerSettings(lbi.getAlgorithm(), lbi.getParameters()); }
2.4 Driver UDP broadcasting state
The driver management MBean has a read-write attribute which allows monitoring and setting its ability to boradcast its connection information to clients, nodes or other servers, via UDP. This atribute is defined via the following accessors:
public interface JPPFDriverAdminMBean extends JPPFAdminMBean { // Determine whether the driver is broadcasting Boolean isBroadcasting() throws Exception; // Activate or deactivate the broadcasting of the driver's connection information void setBroadcasting(Boolean broadcasting) throws Exception; }
3 Information about the nodes
The driver MBean allows monitoring and managing the nodes attached tot he driver with the following two methods:
public interface JPPFDriverAdminMBean extends JPPFAdminMBean { // Request the JMX connection information for all nodes attached to the server public Collection<JPPFManagementInfo> nodesInformation() throws Exception; // Request the JMX connection information for all nodes which satisfy the node selector public Collection<JPPFManagementInfo> nodesInformation(NodeSelector selector) throws Exception; // Get the number of nodes currently attached to the server. public Integer nbNodes() throws Exception; // Get the number of nodes attached to the driver that satisfy the specified selector public Integer nbNodes(NodeSelector selector) throws Exception; }
Note that the methods using a node selector as input parameter provide a lot of flexibility in chosing which nodes to get information about.
The JPPFManagementInfo objects returned in the resulting collection encapsulate enough information to connect to the corresponding node's MBean server:
public class JPPFManagementInfo implements Serializable, Comparable<JPPFManagementInfo> { // Get the host on which the driver or node is running public synchronized String getHost(); // Get the ip address of the host on which the node or driver is running public String getIpAddress() // Get the port on which the node's JMX server is listening public synchronized int getPort() // Get the driver or node's unique id public String getUuid() // Determine whether this is a driver connected as a node to another driver public boolean isPeer() // Determine whether this information represents a real node public boolean isNode() // Determine whether this is a driver public boolean isDriver() // Determine whether communication is be secured via SSL/TLS public boolean isSecure() // Whether this information represents a master node for provisioning public boolean isMasterNode() // Whether this information represents a slave node for provisioning public boolean isSlaveNode() { // Determine whether the node is active or inactive public boolean getMasterUuid() // Determine whether this information represents a local node public boolean isLocal() // Determine whether the node is active or inactive public boolean isActive() }
For example, we could write code that gathers connection information for all the nodes that have less than 1 GB of heap, and then restarts each of them:
JMXDriverConnectionWrapper driver = ...; // select the nodes with less than 1 GB of heap NodeSelector selector = new ExecutionPolicySelector(new LessThan("maxMemory", 1024 * 1024 * 1024)); // Obtain connection information for all attached nodes for (JPPFManagementInfo info: driver.nodesInformation(selector)) { // create a JMX connection wrapper based on the node information JMXNodeConnectionWrapper node = new JMXNodeConnectionWrapper(info.getHost(), info.getPort()); // connect to the node's MBean server if (node.connectAndWait(5000L)) { // restart the node node.restart(); } }
Additionally, if all you need is the number of nodes attached to the server, then simply calling the nbNodes() method will be much more efficient in terms of CPU usage and network traffic.
3.1 Monitoring idle nodes
The JPPF driver MBean provides two methods to gather information on idle nodes:
public interface JPPFDriverAdminMBean extends JPPFAdminMBean { // Request information on the idle nodes attached to the server public Collection<JPPFManagementInfo> idleNodesInformation() throws Exception; // Request information on all idle nodes which satisfy the node selector public Collection<JPPFManagementInfo> idleNodesInformation(NodeSelector selector) throws Exception; // Get the number of idle nodes attached to the server public Integer nbIdleNodes() throws Exception; // Get the number of idle nodes that satisfy the specified selector public Integer nbIdleNodes(NodeSelector selector) throws Exception; }
idlesNodesInformation() is similar to nodesInformation() except that it provides information only for the nodes that are currently idle. If all you need is the number of idle nodes, then it is much less costly to call nbIdleNodes() instead.
3.2 Nodes active state
From the server's perspective, the nodes can be considered either active or inactive. When a node is “active” the server will take it into account when scheduling the execution of the jobs. Inversely, when it is “inactive”, no job can be scheduled to execute on this node. In this case, the node behaves as if it were not part of the JPPF grid for job scheduling purposes, while still being alive and manageable.
This provides a way to disable nodes without the cost of terminating the corresponding remote process. For example, this provides a lot of flexibility in how the workload can be balanced among the nodes: sometimes you may need to have more nodes with less processing threads each, while at other times you could dynamically setup less nodes with more processing threads.
This can be done with the following methods:
public interface JPPFDriverAdminMBean extends JPPFAdminMBean { // Toggle the activate state of the specified nodes public void toggleActiveState(NodeSelector selector) throws Exception; // Get the active states of the nodes specified vith a NodeSelector Map<String, Boolean> getActiveState(NodeSelector selector) throws Exception; // Set the active state of the specified nodes void setActiveState(NodeSelector selector, boolean active) throws Exception; }
The toggleActiveState() method acts as an on/off switch: nodes in the 'active' state will be deactivated, whereas nodes in the 'inactive' state will be activated. Also note that this method uses a node selector to specifiy which nodes it applies to.
The following example retrieves the active state of all the nodes, then reactivates the nodes that are not active:
JMXDriverConnectionWrapper driver = ...; // get the active state of all the nodes Map<String, Boolean> stateMap = driver.getActiveState(NodeSelector.ALL_NODES); // extract the uuids of the inactive nodes List<String> inactiveNodes = stateMap.entrySet().stream() .filter(entry -> !entry.getValue()) .map(entry -> entry.getKey()) .collect(Collectors.toList()); // activate all inactive nodes driver.setActiveState(new UuidSelector(inactiveNodes), true);
4 Managing and monitoring the jobs
The management and monitoring of the jobs in a JPPF driver is performed with an MBean whose name is “org.jppf:name=jobManagement,type=driver”, which is also the value of the DriverJobManagementMBean.MBEAN_NAME constant. This MBean exposes the DriverJobManagementMBean interface, defined as follows:
public interface DriverJobManagementMBean extends NotificationEmitter { // Cancel the job with the specified id public void cancelJob(String jobUuid) throws Exception; // Cancel the selected jobs public void cancelJobs(JobSelector selector) throws Exception; // Suspend the job with the specified id public void suspendJob(String jobUuid, Boolean requeue) throws Exception; // Suspend the selected jobs public void suspendJobs(JobSelector selector, Boolean requeue) throws Exception; // Resume the job with the specified id public void resumeJob(String jobUuid) throws Exception; // Resume the selected jobs public void resumeJobs(JobSelector selector) throws Exception; // Update the maximum number of nodes a job can run on public void updateMaxNodes(String jobUuid, Integer maxNodes) throws Exception; // Update the maximum number of nodes for the selected jobs public void updateMaxNodes(JobSelector selector, Integer maxNodes) throws Exception; // Update the priority of a job void updatePriority(String jobUuid, Integer newPriority); // Update the priority the selected jobs void updatePriority(JobSelector selector, Integer newPriority); // Get the set of uuids of all the jobs currently queued or executing public String[] getAllJobUuids() throws Exception; // Get an object describing the job with the specified uuid public JobInformation getJobInformation(String jobUuid) throws Exception; // Get information on the selected jobs public JobInformation[] getJobInformation(JobSelector selector) throws Exception; // Get a list of objects describing the nodes to which the whole // or part of a job was dispatched public NodeJobInformation[] getNodeInformation(String jobUuid) throws Exception; // Get the list of dispatches for each of the selected nodes public Map<String, NodeJobInformation[]> getNodeInformation(JobSelector selector) throws Exception; }
4.1 Job selectors
Many of the methods in DriverJobManagementMBean use a JobSelector, which allows filtering the jobs in the driver's queue according to user-defined criteria. Any job monitoring function or management request will only apply to the jobs selected by the provided selector. A job seletor is always evaluated against the most recent state of the driver's job queue, therefore the set of jobs selected by a job selector may vary over time.
Job selectors are described in full details in a dedicated section of this documentation.
4.2 Controlling a job's life cycle
It is possible to cancel (i.e. terminate), suspend and resume a job using the following methods:
public interface DriverJobManagementMBean extends NotificationEmitter { // Cancel the job with the specified uuid public void cancelJob(String jobUuid) throws Exception; // Cancel the selected jobs public void cancelJobs(JobSelector selector) throws Exception; // Suspend the job with the specified uuid public void suspendJob(String jobUuid, Boolean requeue) throws Exception; // Suspend the selected jobs public void suspendJobs(JobSelector selector, Boolean requeue) throws Exception; // Resume the job with the specified uuid public void resumeJob(String jobUuid) throws Exception; // Resume the selected jobs public void resumeJobs(JobSelector selector) throws Exception; }
When a job is cancelled, the cancellation request is propagated to all the nodes where the job is currently dispatched. The driver will not wait for the cancellation of the job dispatches. It will return the tasks in each dispatch as if they were never executed, regardless of whether the corresponding nodes actually executed these tasks.
The suspendJob*() methods disable the execution scheduling for one or more jobs. Note that these methods take a Boolean parameter requeue, which determines how the job dispatches of the suspended job are processed:
- if true, then the job dispatches are cancelled and inserted back into the server queue, for execution at a later time (when resuming the job)
- if false, the JPPF driver will let the job dispatches finish executing in the node, then suspend the rest of the job still in the driver queue
If a job is already suspended, then calling one of the suspendJob*() methods that applies to it has no effect.
Suspended jobs can be resumed with one of the resumeJob*() methods, which marks them again as enabled for execution scheduling. If a job was not suspended, then attempting to resume it has no effect.
Here is an example usage of these mzthods:
try (JPPFClient client = new JPPFClient()) { JPPFJob[] jobs = { new JPPFJob().setName("job 1"), new JPPFJob().setName("job 2"), new JPPFJob().setName("job 3") }; // add tasks to the jobs ... // then submit the jobs asynchronusly for (JPPFJob job: jobs) { client.submitAsync(job); } JMXDriverConnectionWrapper driver = client.awaitWorkingConnectionPool().awaitWorkingJMXConnection(); DriverJobManagementMBean jobManager = driver.getJobManager(); // cancel "job 1" jobManager.cancelJob(jobs[0].getUuid()); // suspend "job 2" and "job 3" JobSelector selector = new JobNameSelector("job 2", "job 3"); jobManager.suspendJobs(selector, true); // wait for "job 1" completion jobs[0].awaitResults(); // resume "job 2" and "job 3" jobManager.resumeJobs(selector); }
4.3 Maximum number of nodes assigned to a job
The job SLA's maxNode attribute specifies the maximum number of concurrent nodes a job can be dispatched to at any given time. This attribute can be updated dynamically with the following methods of DriverJobManagementMBean:
public interface DriverJobManagementMBean extends NotificationEmitter { // Update the maximum number of nodes a job can run on. public void updateMaxNodes(String jobUuid, Integer maxNodes) throws Exception; // Update the maximum number of nodes for the selected jobs public void updateMaxNodes(JobSelector selector, Integer maxNodes) throws Exception; }
Example usage:
JMXDriverConnectionWrapper driver = ...; DriverJobManagementMBean jobManager = driver.getJobManager(); // select the jobs whose name starts with 'maintenance' JobSelector selector = new RegexJobSelector("^maintenance.*"); // ensure the 'maintenance' jobs don't execute on more than 1 node at a time jobManager.updateMaxNodes(selector, 1);
4.4 Updating the priority of a job
The following methods dynamically update the priority of the specified jobs, with an immediate effect:
public interface DriverJobManagementMBean extends NotificationEmitter { // Update the priority of a job void updatePriority(String jobUuid, Integer newPriority); // Update the priority the selected jobs void updatePriority(JobSelector selector, Integer newPriority); }
Example usage:
DriverJobManagementMBean jobManager = ...; // select the jobs that have a metadata element 'importance' whose value is 'HIGH' JobSelector selector = new EqualsJobSelector("importance", JobImportance.HIGH); // increase the priority of 'high importance' jobs to 100 jobManager.updatePriority(selector, 100);
4.5 Updating the job SLA and metadata
The SLA and metadata of one or more jobs can be updated dynamically, together, atomically and as a whole. This is done with the following method:
public interface DriverJobManagementMBean extends NotificationEmitter { // Update the SLA and/or metadata of the specified jobs void updateJobs(JobSelector selector, JobSLA sla, JobMetadata metadata); }
Note that, if any or both of the sla and metadata parameters are null, they will be ignored. To perform the update on a single job, use a JobUuidSelector as follows:
JPPFJob job = ...; JobSelector selector = new JobUuidSelector(job.getUuid());
Below is an example using this feature:
// get a proxy to the job management MBean DriverJobManagementMBean jobManager = ...; // create the job and add tasks JPPFJob job = createJob(); JobSLA sla = job.getSLA(); // disable execution on master nodes sla.setExecutionPolicy(new IsMasterNode().not()); // submit the job asynchronously and do something else client.submitAsync(job); ... // remove the execution policy to allow execution on all nodes sla.setExecutionPolicy(null); // now update the SLA for our job jobManager.updateJobs(new JobUuidSelector(job.getUuid()), sla, null); ...
4.6 Job introspection
The management features allow users to query and inspect the jobs currently queued or executing in the driver. This can be done using the related methods of the jobs management MBean:
public interface DriverJobManagementMBean extends NotificationEmitter { // Get the set of uuids for all the jobs currently queued or executing public String[] getAllJobUuids() throws Exception; // Get an object describing the job with the specified uuid public JobInformation getJobInformation(String jobUuid) throws Exception; // Get information on the selected jobs public JobInformation[] getJobInformation(JobSelector selector) throws Exception; // Get a list of objects describing the nodes to which the whole // or part of a job was dispatched public NodeJobInformation[] getNodeInformation(String jobUuid) throws Exception; // Get the list of dispatches for each of the selected nodes public Map<String, NodeJobInformation[]> getNodeInformation(JobSelector selector) throws Exception; }
The getAllJobUuids() method returns the UUIDs of all the jobs currently handled by the server. These UUIDs can be directly used with the other methods of the job management MBean.
The getJobInformation(...) methods retrieve information about the state of the specified job(s) in the server. These methods return one or more objects of type JobInformation, defined as follows:
public class JobInformation implements Serializable { // the job's name public String getJobName() // the current number of tasks in the job or sub-job public int getTaskCount() // the priority of this task bundle public int getPriority() // the initial task count of the job (at submission time) public int getInitialTaskCount() // determine whether the job is in suspended state public boolean isSuspended() // set the maximum number of nodes this job can run on public int getMaxNodes() // the pending state of the job // a job is pending if its scheduled execution date/time has not yet been reached public boolean isPending() }
The getNodeInformation(...) methods also allow to obtain information about all the subsets of a job that are disptached to remote nodes. The return value is an array of objects of type NodeJobInformation, or a map of job uuid to such an array if using a selector, defined as follows:
public class NodeJobInformation implements Serializable { // Get the information about the node. public JPPFManagementInfo getNodeInfo() // Get the information about the job dispatch public JobInformation getJobInformation() }
This class is simply a grouping of two objects of type JobInformation and JPPFManagementInfo, which we have already seen previously. The nodeInfo attribute will allow us to connect to the corresponding node's MBean server and obtain additional job monitoring data.
Please also note that the method getNodeInformation(JobSelector) returns a mapping of job uuids to their corresponding node dispatches.
The following example prints the number of nodes each job in the driver is dispatched to:
DriverJobManagementMBean jobManager = ...; // get the node dispatch information for all the jobs Map<String, NodeJobInformation[]> jobMap = jobManager.getNodeInformation(JobSelector.ALL_JOBS); // for each job, display its name and the number of nodes it is dispatched to for (Map.Entry<String, NodeJobInformation[]> entry: jobMap.entrySet()) { NodeJobInformation[] infos = entry.getValue(); if ((infos != null) && (infos.length > 0)) { JobInformation jobInfo = infos[0].getJobInformation(); System.out.println("job " + jobInfo.getJobName() + " is dispatched to " + infos.length + " nodes"); } }
4.7 Job notifications
Whenever a job-related event occurs, the job management MBean will emit a notification of type JobNotification:
public class JobNotification extends Notification { // the information about the job or sub-job public JobInformation getJobInformation() // the information about the node the job is dispatched to, if relevant, otherwise null public JPPFManagementInfo getNodeInfo() // the creation timestamp for this event public long getTimestamp() // the type of this job event public JobEventType getEventType() // Get the uuid of the driver which emitted the notification public String getDriverUuid() }
The value of the job event type (see the JobEventType enumeration) is one of the following:
- JOB_QUEUED: a new job was submitted to the JPPF driver queue
- JOB_ENDED: a job was completed and sent back to the client
- JOB_DISPATCHED: the job was dispatched to a node
- JOB_RETURNED: a job dispatch returned from a node
- JOB_UPDATED: one of the job attributes has changed
The following example prints a message whenever a job is dispatched to a node or a job dispatch returns from a node:
DriverJobManagementMBean jobManager = ...; // define a job notifications listener that prints jobs dispatch and return information NotificationListener listener = (notification, handback) -> { JobNotification jobNotif = (JobNotification) notification; String jobName = jobNotif.getJobInformation().getJobName(); JPPFManagementInfo nodeInfo = jobNotif.getNodeInfo(); // print job dispatch and return information for the job switch(jobNotif.getEventType()) { case JOB_DISPATCHED: System.out.println("job " + jobName + " dispatched to node " + nodeInfo); break; case JOB_RETURNED: System.out.println("job " + jobName + " returned from node " + nodeInfo); break; } }; // register the job notifications listener jobManager.addNotificationListener(listener, null, null); // ... submit jobs ... ... // unregister the job notifications listener when it's no longer needed jobManager.removeNotificationListener(listener);
Main Page > Management and monitoring > Driver management |