Author: burn Date: Wed Oct 9 20:22:22 2019 New Revision: 1868201 URL: http://svn.apache.org/viewvc?rev=1868201&view=rev Log: UIMA-6130 Add buttons to toggle the state to mark a task to be rerun
Modified: uima/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/handlers/experiments/HandlerExperimentsServlets.java uima/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/xd/Experiment.java uima/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/xd/IExperiment.java uima/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/xd/Jed.java uima/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/xd/Task.java uima/uima-ducc/trunk/uima-ducc-web/src/main/webapp/root/experiment.details.jsp uima/uima-ducc/trunk/uima-ducc-web/src/main/webapp/root/js/ducc.js uima/uima-ducc/trunk/uima-ducc-web/src/main/webapp/root/js/ducc.local.js Modified: uima/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/handlers/experiments/HandlerExperimentsServlets.java URL: http://svn.apache.org/viewvc/uima/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/handlers/experiments/HandlerExperimentsServlets.java?rev=1868201&r1=1868200&r2=1868201&view=diff ============================================================================== --- uima/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/handlers/experiments/HandlerExperimentsServlets.java (original) +++ uima/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/handlers/experiments/HandlerExperimentsServlets.java Wed Oct 9 20:22:22 2019 @@ -94,13 +94,11 @@ public class HandlerExperimentsServlets private long getRunTime(HttpServletRequest request, IExperiment experiment) { long runTime = 0; - if (experiment.getTasks() != null) { - ArrayList<Task> tasks = experiment.getTasks(); - for (Task task : tasks) { - if (task.parentId == 0) { - if (task.runTime > runTime) { - runTime = task.runTime; - } + Task[] tasks = experiment.getTasks(); + for (Task task : tasks) { + if (task.parentId == 0) { + if (task.runTime > runTime) { + runTime = task.runTime; } } } @@ -137,14 +135,6 @@ public class HandlerExperimentsServlets return user; } - private String getTasks(HttpServletRequest request, IExperiment experiment) { - String tasks = "0"; - if (experiment.getTasks() != null) { - tasks = "" + experiment.getTasks().size(); - } - return tasks; - } - private String getState(HttpServletRequest request, IExperiment experiment) { String health; Status experimentStatus = experiment.getStatus(); @@ -201,25 +191,22 @@ public class HandlerExperimentsServlets fmt.startRow(); String terminate = ""; - if (terminateEnabled) { - Status experimentStatus = experiment.getStatus(); - switch (experimentStatus) { - case Running: - String id = experiment.getId(); - String directory = experiment.getDirectory(); - String disabled = ""; - String resourceOwnerUserid = experiment.getUser(); - if (!HandlersHelper.isUserAuthorized(request, resourceOwnerUserid)) { - // Set the disabled attribute and a hover for the greyed-out button - disabled = "disabled title=\"Hint: use Login to enable\""; - } - String p0 = "'" + id + "'"; - String p1 = "'" + directory + "'"; - terminate = "<input type=\"button\" onclick=\"ducc_confirm_terminate_experiment(" + p0 - + "," + p1 + ")\" value=\"Terminate\" " + disabled + "/>"; - default: - break; - } + Status experimentStatus = experiment.getStatus(); + switch (experimentStatus) { + case Running: + String id = experiment.getId(); + String directory = experiment.getDirectory(); + String disabled = ""; + String resourceOwnerUserid = experiment.getUser(); + if (!HandlersHelper.isUserAuthorized(request, resourceOwnerUserid)) { + // Set the disabled attribute and a hover for the greyed-out button + disabled = "disabled title=\"Hint: use Login to enable\""; + } + terminate = "<input type=\"button\"" + + " onclick=\"ducc_confirm_terminate_experiment('" + id + "','" + directory + "')\"" + + " value=\"Terminate\" " + disabled + "/>"; + default: + break; } fmt.addElemR(terminate); fmt.addElemL(getStartDate(request, experiment)); @@ -230,7 +217,7 @@ public class HandlerExperimentsServlets fmt.addElemR(duration, runTime); fmt.addElemL(getUser(request, experiment)); - fmt.addElemR(getTasks(request, experiment)); + fmt.addElemR(experiment.getTasks().length); fmt.addElemL(getState(request, experiment)); fmt.addElemL(getDirectoryLink(request, experiment)); @@ -256,32 +243,43 @@ public class HandlerExperimentsServlets return handled; } - private String decorateState(IExperiment experiment, Task task) { + private String decorateState(IExperiment experiment, Task task, boolean isRestartable) { String mName = "decorateState"; String state = ""; if (task.status != null) { state = task.status; - String type = task.type; - boolean leaf = Jed.Type.isLeaf(type); - if (leaf) { - Jed.Status status = Jed.Status.getEnum(state); - switch (status) { - case Running: - if (experiment.isStale()) { - state = "<span class=\"health_red\">Unknown"; - WsLog.info(cName, mName, experiment.getDirectory() + " " + "stale:" + task.taskId); - } else { - state = "<span class=\"health_green\">Running"; + Jed.Status status = Jed.Status.getEnum(state); + switch (status) { + case Running: + if (experiment.isStale()) { + state = "<span class=\"health_red\">Unknown"; + WsLog.info(cName, mName, experiment.getDirectory() + " " + "stale:" + task.taskId); + } else { + state = "<span class=\"health_green\">Running"; + } + break; + case Failed: + case DependencyFailed: + case Canceled: + state = "<span class=\"health_red\"" + ">" + state + "</span>"; + break; + case Completed: + case Done: + // If experiment can be restarted display a toggle button + if (isRestartable) { + String color = ""; + if (task.rerun) { + state = "Rerun"; + color = " style='background-color:palegreen'"; } - break; - case Failed: - case DependencyFailed: - case Canceled: - state = "<span class=\"health_red\"" + ">" + state + "</span>"; - break; - default: - break; - } + state = "<input type=\"button\"" + color + + " onclick=\"ducc_toggle_task_state('" + experiment.getId() + "','" + task.taskId + "')\"" + + " title=\"Click to toggle state\"" + + " value=\"" + state + "\" />"; + } + break; + default: + break; } } return state; @@ -363,7 +361,7 @@ public class HandlerExperimentsServlets } private void edTaskDucc(FormatServlet fmt, IExperiment experiment, Task task, - HttpServletRequest request, long duccId, long now) { + HttpServletRequest request, long duccId, long now, boolean isRestartable) { DuccData duccData = DuccData.getInstance(); // Format first 8 columns: @@ -372,7 +370,7 @@ public class HandlerExperimentsServlets fmt.addElemR(task.taskId); fmt.addElemR(task.parentId); fmt.addElemL(task.name); - fmt.addElemL(decorateState(experiment, task)); + fmt.addElemL(decorateState(experiment, task, isRestartable)); fmt.addElemL(task.type); fmt.addElemL(decorateStepStart(task, request)); fmt.addElemR(decorateStepDuration(task), task.runTime); @@ -427,26 +425,43 @@ public class HandlerExperimentsServlets String id = request.getParameter("id"); IExperiment experiment = experimentsRegistryManager.getById(id); - + long now = System.currentTimeMillis(); FormatServlet fmt = tableStyle.equals("scroll") ? new FormatServletScroll() : new FormatServletClassic(); if (experiment != null) { - ArrayList<Task> tasks = experiment.getTasks(); + // Check if the experiment can be restarted, i.e. + // launched by DUCC, stopped, and owned by the logged-in user + // ?? Could be an experiment attribute? + boolean duccLaunched = true; // TODO ... FIX! + boolean isRestartable = duccLaunched + && experiment.getStatus() != Jed.Status.Running + && HandlersHelper.isUserAuthorized(request, experiment.getUser()); + + Task[] tasks = experiment.getTasks(); if (tasks != null) { + // Check if given a task whose state is to be toggled between Completed & Rerun + String toggleTask = request.getParameter("taskid"); + if (toggleTask != null) { + WsLog.info(cName, mName, "!! id = '"+id+"' taskid = '"+toggleTask+"'"); + int toggle = Integer.parseInt(toggleTask); + Task task = tasks[toggle-1]; + task.rerun = !task.rerun; + markSubtasks(tasks, toggle, task.rerun); + } for (Task task : tasks) { long latestDuccId = 0; String type = (task.type != null) ? task.type : ""; Jed.Type jedType = Jed.Type.getEnum(type); - if (jedType == Jed.Type.DuccJob || jedType == Jed.Type.Java) { + if (jedType == Jed.Type.Ducc_Job || jedType == Jed.Type.Java) { long[] duccIds = task.duccId; int nIds = duccIds.length; latestDuccId = nIds == 0 ? 0 : duccIds[--nIds]; //String otherIds = reverse(duccIds, nIds); } fmt.startRow(); - edTaskDucc(fmt, experiment, task, request, latestDuccId, now); + edTaskDucc(fmt, experiment, task, request, latestDuccId, now, isRestartable); fmt.endRow(); } } @@ -467,6 +482,17 @@ public class HandlerExperimentsServlets return handled; } + // Mark each child with the same rerun state as the parent. + // Note that children ALWAYS have a larger taskId + private void markSubtasks(Task[] tasks, int parentId, boolean rerun) { + for (int childId = parentId + 1; childId <= tasks.length; ++childId) { + if (tasks[childId-1].parentId == parentId) { + tasks[childId-1].rerun = rerun; + markSubtasks(tasks, childId, rerun); + } + } + } + private boolean handleServletExperimentDetailsDirectory(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws Exception { String mName = "handleServletExperimentDetailsDirectory"; Modified: uima/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/xd/Experiment.java URL: http://svn.apache.org/viewvc/uima/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/xd/Experiment.java?rev=1868201&r1=1868200&r2=1868201&view=diff ============================================================================== --- uima/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/xd/Experiment.java (original) +++ uima/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/xd/Experiment.java Wed Oct 9 20:22:22 2019 @@ -36,7 +36,7 @@ public class Experiment implements IExpe private String id = UUID.randomUUID().toString(); private int version; - + public Experiment(String user, String directory, long date, int version, ArrayList<Task> tasks) throws Exception { initialize(user, directory, date, version, tasks); @@ -80,11 +80,17 @@ public class Experiment implements IExpe return directory; } + // Create an array indexed by taskId-1 @Override - public ArrayList<Task> getTasks() { - return tasks; + public Task[] getTasks() { + int size = tasks==null ? 0 : tasks.size(); + Task[] tasksArray = new Task[size]; + for (Task task : tasks) { + tasksArray[task.taskId-1] = task; + } + return tasksArray; } - + @Override public ArrayList<String> getJobIds() { ArrayList<String> jobIds = new ArrayList<String>(); @@ -93,7 +99,7 @@ public class Experiment implements IExpe if (task.type != null) { Jed.Type jedType = Jed.Type.getEnum(task.type); switch (jedType) { - case DuccJob: + case Ducc_Job: case Java: case Trainer: long[] duccIdList = task.duccId; @@ -137,7 +143,7 @@ public class Experiment implements IExpe @Override public Jed.Status getStatus() { Jed.Status retVal = Jed.Status.Unknown; - ArrayList<Task> tasks = getTasks(); + Task[] tasks = getTasks(); if (tasks != null) { boolean canceled = false; boolean failed = false; @@ -341,5 +347,4 @@ public class Experiment implements IExpe } return retVal; } - } Modified: uima/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/xd/IExperiment.java URL: http://svn.apache.org/viewvc/uima/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/xd/IExperiment.java?rev=1868201&r1=1868200&r2=1868201&view=diff ============================================================================== --- uima/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/xd/IExperiment.java (original) +++ uima/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/xd/IExperiment.java Wed Oct 9 20:22:22 2019 @@ -29,7 +29,7 @@ public interface IExperiment extends Com public String getDirectory(); - public ArrayList<Task> getTasks(); + public Task[] getTasks(); public ArrayList<String> getJobIds(); Modified: uima/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/xd/Jed.java URL: http://svn.apache.org/viewvc/uima/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/xd/Jed.java?rev=1868201&r1=1868200&r2=1868201&view=diff ============================================================================== --- uima/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/xd/Jed.java (original) +++ uima/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/xd/Jed.java Wed Oct 9 20:22:22 2019 @@ -22,7 +22,7 @@ public class Jed { public enum Type { - DuccJob, Java, File, Exec, Trainer, Sequential, Parallel, ParallelData, SetPhase, Other; + Ducc_Job, Java, File, Exec, Trainer, Sequential, Sequential_Data, Parallel, Parallel_Data, Set_Phase, Other; private static String DUCC_JOB = "DUCC_JOB"; @@ -33,14 +33,8 @@ public class Jed { public static Type getEnum(String value) { Type retVal = Other; if (value == null) { - } else if (DUCC_JOB.equalsIgnoreCase(value)) { - retVal = DuccJob; - } else if (PARALLEL_DATA.equalsIgnoreCase(value)) { - retVal = ParallelData; - } else if (SET_PHASE.equalsIgnoreCase(value)) { - retVal = SetPhase; - } else if (DuccJob.name().equalsIgnoreCase(value)) { - retVal = DuccJob; + } else if (Ducc_Job.name().equalsIgnoreCase(value)) { + retVal = Ducc_Job; } else if (Java.name().equalsIgnoreCase(value)) { retVal = Java; } else if (File.name().equalsIgnoreCase(value)) { @@ -51,12 +45,14 @@ public class Jed { retVal = Trainer; } else if (Sequential.name().equalsIgnoreCase(value)) { retVal = Sequential; - } else if (ParallelData.name().equalsIgnoreCase(value)) { - retVal = ParallelData; + } else if (Sequential_Data.name().equalsIgnoreCase(value)) { + retVal = Sequential_Data; + } else if (Parallel_Data.name().equalsIgnoreCase(value)) { + retVal = Parallel_Data; } else if (Parallel.name().equalsIgnoreCase(value)) { retVal = Parallel; - } else if (SetPhase.name().equalsIgnoreCase(value)) { - retVal = SetPhase; + } else if (Set_Phase.name().equalsIgnoreCase(value)) { + retVal = Set_Phase; } return retVal; } @@ -66,8 +62,9 @@ public class Jed { if (value != null) { switch (value) { case Parallel: - case ParallelData: + case Parallel_Data: case Sequential: + case Sequential_Data: retVal = false; break; default: Modified: uima/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/xd/Task.java URL: http://svn.apache.org/viewvc/uima/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/xd/Task.java?rev=1868201&r1=1868200&r2=1868201&view=diff ============================================================================== --- uima/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/xd/Task.java (original) +++ uima/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/xd/Task.java Wed Oct 9 20:22:22 2019 @@ -42,4 +42,6 @@ public class Task { public int[] subTasks = new int[0]; public long[] duccId = new long[0]; + + public boolean rerun = false; // Note - this is NOT in the Experiment.state file } Modified: uima/uima-ducc/trunk/uima-ducc-web/src/main/webapp/root/experiment.details.jsp URL: http://svn.apache.org/viewvc/uima/uima-ducc/trunk/uima-ducc-web/src/main/webapp/root/experiment.details.jsp?rev=1868201&r1=1868200&r2=1868201&view=diff ============================================================================== --- uima/uima-ducc/trunk/uima-ducc-web/src/main/webapp/root/experiment.details.jsp (original) +++ uima/uima-ducc/trunk/uima-ducc-web/src/main/webapp/root/experiment.details.jsp Wed Oct 9 20:22:22 2019 @@ -28,18 +28,25 @@ if (table_style.equals("scroll")) { %> <!-- Drop the sAjaxSource entry as it caused a superfluous request without a row id --> <!-- Also drop the bSortable:false for the 1st column (the experiment id) --> + <!-- Options: --> + <!-- Processing - display Processing message --> + <!-- dom - positions the various controls that DataTables adds to the table --> + <!-- (Length,Filtering,pRocessing,Table,Information,Paging) --> + <!-- Colvis - reserves a row (avoids "Processing" page bounce) --> + <script type="text/javascript" charset="utf-8"> var oTable; $(document).ready(function() { oTable = $('#experiment-details-table').dataTable( { - "bProcessing": true, - "bPaginate": false, - "bFilter": true, - "sScrollX": "100%", - "sScrollY": "600px", - "bInfo": false, - "aaSorting": [], - "fnRowCallback" : function(nRow,aData,iDisplayIndex) { + dom: 'Clfrtip', + processing: true, + paging: false, + searching: true, + scrollX: "100%", + scrollY: "600px", + info: false, + order: [], + rowCallback : function(nRow,aData,iDisplayIndex) { return nRow; }, } ); @@ -98,9 +105,10 @@ if (table_style.equals("scroll")) { <table id="experiment-details-table" width="100%"> <thead> <tr class="ducc-header"> + <th title="The path id for this experiment subtask">Path Id</th> <th title="The id for this experiment subtask" class="sorttable_numeric">Id</th> - <th title="The name for this experiment subtask">Name</th> <th title="The parent id for this experiment subtask" class="sorttable_numeric">Parent</th> + <th title="The name for this experiment subtask">Name</th> <th title="The state of this experiment subtask">State</th> <th title="The type for this experiment subtask">Type</th> <th title="The start time of this experiment subtask">Step<br>Start</th> @@ -131,15 +139,16 @@ if (table_style.equals("classic")) { <table class="sortable"> <thead> <tr class="ducc-head"> + <th title="The path id for this experiment subtask">Path Id</th> <th title="The id for this experiment subtask" class="sorttable_numeric">Id</th> - <th title="The name for this experiment subtask">Name</th> - <th title="The parent id for this experiment subtask" class="sorttable_numeric">Parent</th> - <th title="The state of this experiment subtask">State</th> - <th title="The type for this experiment subtask">Type</th> - <th title="The start time of this experiment subtask">Step<br>Start</th> - <th class="sorttable_numeric" title="The duration time of this experiment subtask">Step<br>Duration</th> + <th title="The parent id for this experiment subtask" class="sorttable_numeric">Parent</th> + <th title="The name for this experiment subtask">Name</th> + <th title="The state of this experiment subtask">State</th> + <th title="The type for this experiment subtask">Type</th> + <th title="The start time of this experiment subtask">Step<br>Start</th> + <th class="sorttable_numeric" title="The duration time of this experiment subtask">Step<br>Duration</th> <th title="The DUCC Id(s) for this experiment subtask, if any">DUCC Id</th> - <th class="sorttable_numeric" title="The duration time of this DUCC subtask">DUCC<br>Duration</th> + <th class="sorttable_numeric" title="The duration time of this DUCC subtask">DUCC<br>Duration</th> <th title="The total number of work items for this job">Total</th> <th title="The number of work items that completed successfully">Done</th> <th title="The number of work items that failed to complete successfully">Error</th> Modified: uima/uima-ducc/trunk/uima-ducc-web/src/main/webapp/root/js/ducc.js URL: http://svn.apache.org/viewvc/uima/uima-ducc/trunk/uima-ducc-web/src/main/webapp/root/js/ducc.js?rev=1868201&r1=1868200&r2=1868201&view=diff ============================================================================== --- uima/uima-ducc/trunk/uima-ducc-web/src/main/webapp/root/js/ducc.js (original) +++ uima/uima-ducc/trunk/uima-ducc-web/src/main/webapp/root/js/ducc.js Wed Oct 9 20:22:22 2019 @@ -34,7 +34,8 @@ if(!String.startsWith) { var oTable; var display_table_style; -var ms_reload_min = 5000; +// Ignore any repeat requests less tha 1 sec apart +var ms_reload_min = 1000; var ms_timeout = 25000; Modified: uima/uima-ducc/trunk/uima-ducc-web/src/main/webapp/root/js/ducc.local.js URL: http://svn.apache.org/viewvc/uima/uima-ducc/trunk/uima-ducc-web/src/main/webapp/root/js/ducc.local.js?rev=1868201&r1=1868200&r2=1868201&view=diff ============================================================================== --- uima/uima-ducc/trunk/uima-ducc-web/src/main/webapp/root/js/ducc.local.js (original) +++ uima/uima-ducc/trunk/uima-ducc-web/src/main/webapp/root/js/ducc.local.js Wed Oct 9 20:22:22 2019 @@ -106,7 +106,7 @@ var ms_load_experiments_data = +n // // Drop thw work-in-progress check as the ms_reload_min check should block any simultaneous requests ... how do they occur? -function ducc_load_data(type) { +function ducc_load_data(type, params) { // Check if too soon after the last use var ms_now = +new Date(); type_ = type.replace(/-/g, '_'); @@ -115,20 +115,23 @@ function ducc_load_data(type) { return; } eval('ms_load_' + type_ + '_data = ms_now'); - + if (params == undefined) { + params = location.search; + } var table_style = ducc_preferences_get("table_style"); if (table_style == "scroll") { - ducc_load_scroll_data(type); + ducc_load_scroll_data(type, params); } else { - ducc_load_classic_data(type); + ducc_load_classic_data(type, params); } } -function ducc_load_classic_data(type) { +function ducc_load_classic_data(type, params) { var fname = 'ducc_load_classic_data/' + type; var data = null; + try { - var servlet = "/ducc-servlet/" + type + "-data" + location.search; + var servlet = "/ducc-servlet/" + type + "-data" + params var tomsecs = ms_timeout; $.ajax({ url: servlet, @@ -147,10 +150,10 @@ function ducc_load_classic_data(type) { } } -function ducc_load_scroll_data(type) +function ducc_load_scroll_data(type, params) { try { - oTable.fnReloadAjax("/ducc-servlet/json-format-aaData-" + type + location.search,ducc_load_scroll_callback); + oTable.fnReloadAjax("/ducc-servlet/json-format-aaData-" + type + params, ducc_load_scroll_callback); } catch(err) { ducc_error("ducc_load_scroll_data/"+type,err); @@ -245,3 +248,13 @@ function ducc_update_page_local(type) ducc_error("ducc_update_page_local",err); } } + +function ducc_toggle_task_state(expid, taskid) +{ + try { + ducc_load_data("experiment-details", "?id="+expid+"&taskid="+taskid); + } + catch(err) { + ducc_error("ducc_toggle_task_state",err); + } +}