in uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/nodeviz/NodeViz.java [119:350]
public void generateVisualization(OrchestratorStateDuccEvent ev)
{
String methodName = "generateVisualization";
Map<String, VisualizedHost> hosts = new HashMap<String, VisualizedHost>();
DuccMachinesData machinesData = DuccMachinesData.getInstance();
IDuccWorkMap jobmap = ev.getWorkMap();
int job_gb = 0;
int service_gb = 0;
int pop_gb = 0;
int reservation_gb = 0;
// Must find host configuration so we can work out the quantum used to schedule each job
String class_definitions = SystemPropertyResolver
.getStringProperty(DuccPropertiesResolver
.ducc_rm_class_definitions, "scheduler.classes");
String user_registry = SystemPropertyResolver
.getStringProperty(DuccPropertiesResolver
.ducc_rm_user_registry, "ducc.users");
class_definitions = System.getProperty("DUCC_HOME") + "/resources/" + class_definitions;
NodeConfiguration nc = new NodeConfiguration(class_definitions, null, user_registry, logger); // UIMA-4142 make the config global
try {
nc.readConfiguration();
} catch (Exception e ) {
logger.error(methodName, null, "Cannot read node configuration. Some information may not be quite right.");
}
// first step, generate the viz from the OR map which seems to have everything we need
// next stop, walk the machines list and generate empty node for any machine in that list
// that had no work on it
// lext step, walk the machines data and overlay a graphic for any node that is 'down' or 'defined'
// move 'down' hosts with jobs on them to the front
// move all onther 'not up' hosts to the end
// finally, walk the list and make them render
for ( Object o : jobmap.values() ) {
IDuccWork w = (IDuccWork) o;
DuccType type = w.getDuccType();
String service_endpoint = null;
String service_id = null; // UIMA-4209
// If it looks service-y and os of deployment type 'other' it's a Pop.
if ( type == DuccType.Service ) {
IDuccWorkService dws = (IDuccWorkService) w;
if ( dws.getServiceDeploymentType() == ServiceDeploymentType.other) {
type = DuccType.Pop;
} else {
service_endpoint = dws.getServiceEndpoint();
service_id = dws.getServiceId(); // UIMA-4209
}
}
if ( ! w.isSchedulable() ) {
logger.debug(methodName, w.getDuccId(), "Ignoring unschedulable work:", w.getDuccType(), ":", w.getStateObject());
continue;
}
IDuccStandardInfo si = w.getStandardInfo();
IDuccSchedulingInfo sti = w.getSchedulingInfo();
String user = si.getUser();
String duccid = service_id == null ? Long.toString(w.getDuccId().getFriendly()) : service_id; // UIMA-4209
int jobmem = (int) (sti.getMemorySizeAllocatedInBytes()/SizeBytes.GB);
String sclass = sti.getSchedulingClass();
int quantum = default_quantum;
try {
quantum = nc.getQuantumForClass(sclass);
} catch ( Exception e ) {
// this most likely caused by a reconfigure so that a job's class no longer exists. nothing to do about it
// but punt and try not to crash.
logger.warn(methodName, null, "Cannot find scheduling class or quantum for " + sclass + ". Using default quantum of " + default_quantum);
}
int qshares = jobmem / quantum;
if ( jobmem % quantum != 0 ) qshares++;
switch ( type ) {
case Job:
case Pop:
case Service:
{
IDuccWorkExecutable de = (IDuccWorkExecutable) w;
IDuccProcessMap pm = de.getProcessMap();
logger.debug(methodName, w.getDuccId(), "Receive:", type, w.getStateObject(), "processes[", pm.size() + "]");
for ( IDuccProcess proc : pm.values() ) {
String pid = proc.getPID();
ProcessState state = proc.getProcessState();
Node n = proc.getNode();
logger.debug(methodName, w.getDuccId(), (n == null ? "N/A" : n.getNodeIdentity().getCanonicalName()), "Process[", pid, "] state [", state, "] is complete[", proc.isComplete(), "]");
if ( proc.isComplete() ) {
continue;
}
switch ( type ) {
case Job:
job_gb += jobmem;
break;
case Pop:
pop_gb += jobmem;
break;
case Service:
service_gb += jobmem;
break;
default:
break;
}
NodeIdentity ni = n.getNodeIdentity();
NodeId nodeId = new NodeId(ni.getCanonicalName());
MachineInfo mi = machinesData.getMachineInfoForNodeid(nodeId);
if ( mi != null ) {
String key = strip(n.getNodeIdentity().getCanonicalName());
VisualizedHost vh = hosts.get(key);
if ( vh == null ) {
// System.out.println("Set host from OR with key:" + key + ":");
vh = new VisualizedHost(mi, quantum);
hosts.put(key, vh);
}
vh.addWork(type, user, duccid, jobmem, qshares, service_endpoint);
}
else {
String message = nodeId.getShortName()+" not found?";
logger.debug(methodName, w.getDuccId(), message);
}
}
}
break;
case Reservation:
{
IDuccWorkReservation de = (IDuccWorkReservation) w;
IDuccReservationMap rm = de.getReservationMap();
logger.debug(methodName, w.getDuccId(), "Receive:", type, w.getStateObject(), "processes[", rm.size(), "] Completed:", w.isCompleted());
reservation_gb += jobmem;
for ( IDuccReservation r: rm.values()) {
Node n = r.getNode();
if ( n == null ) {
logger.debug(methodName, w.getDuccId(), "Node [N/A] mem[N/A");
} else if ( n.getNodeIdentity() == null ) {
logger.debug(methodName, w.getDuccId(), "NodeIdentity [N/A] mem[N/A");
} else {
NodeIdentity ni = n.getNodeIdentity();
NodeId nodeId = new NodeId(ni.getCanonicalName());
MachineInfo mi = machinesData.getMachineInfoForNodeid(nodeId);
if ( mi != null ) {
String key = strip(n.getNodeIdentity().getCanonicalName());
VisualizedHost vh = hosts.get(key);
if ( vh == null ) {
// System.out.println("Set host from OR with key:" + key + ":");
vh = new VisualizedHost(mi, quantum);
hosts.put(key, vh);
}
vh.addWork(type, user, duccid, jobmem, qshares, null);
}
else {
String message = nodeId.getShortName()+" not found?";
logger.debug(methodName, w.getDuccId(), message);
}
}
}
}
break;
default:
logger.warn(methodName, w.getDuccId(), "Received work of type ?", w.getDuccType());
break;
}
}
logger.debug(methodName, null, "Generateing visualizaiton");
Map<MachineInfo,NodeId> m = machineData.getMachines();
for (Entry<MachineInfo, NodeId> entry : m.entrySet()) {
//
// This is for hosts that have no work on them so they didn't come in the work map
//
MachineInfo mi = entry.getKey();
// NOTE: the map changes all the time so the value may be gone. This situation
// will be fixed one day but for now just forget the node, it will show up
// next time we get here.
if ( mi == null ) continue;
String s = mi.getName();
if ( !mi.getStatus().equals("up") ) continue; // filter non-up nodes
String key = strip(s); // our key, possibly with domain stripped
if ( ! hosts.containsKey(key) ) {
VisualizedHost vh = new VisualizedHost(mi, nc.getQuantumForNode(s));
hosts.put(key, vh);
}
}
int total_gb = 0;
Markup markup = new Markup();
VisualizedHost[] sorted = hosts.values().toArray(new VisualizedHost[hosts.size()]);
Arrays.sort(sorted, new HostSorter());
for ( VisualizedHost vh : sorted ) {
vh.toSvg(markup);
total_gb += vh.countRam();
}
String page = markup.close();
int unoccupied_gb = total_gb - (job_gb + pop_gb + service_gb + reservation_gb);
visualization =
"<html>" +
"<div id=\"viz-header\" style=\"text-align:center\">" +
"Sort By " +
"<i onclick=\"ducc_viz_node_sorter('size')\" id=\"ducc-viz-sort-size\" style=\"color:red\">Size </i>" +
"<i onclick=\"ducc_viz_node_sorter('name')\" id=\"ducc-viz-sort-name\"\">Name</i>" +
"</br>" +
"<b>Memory Available:</b> " + total_gb +
"GB, <b>In use: </b>" +
"<b><i>Jobs:</i></b> " + (job_gb) +
"GB, <b><i>Services:</i></b> " + (service_gb) +
"GB, <b><i>Managed Reservations:</i></b> " + (pop_gb) +
"GB, <b><i>Reservations:</i></b> " + (reservation_gb) +
"GB, <b><i>Unoccupied:</i></b> " + (unoccupied_gb) +
"GB</div>" +
"<br>" +
//"<div id=\"nodelist\" style=\"background-color:e5e5e5\">" +
"<div id=\"nodelist\" style=\"background-color:eeeeee;padding:3\">" +
page +
"</div>" +
"<script>" +
"ducc_viz_onreload();" +
"</script>" +
"</html>";
// logger.info(methodName, null, "Size of node visualization:", visualization.length());
hosts = null;
}