azkaban-developers

Adding front end update support.

8/21/2012 9:24:30 PM

Details

diff --git a/src/java/azkaban/executor/ExecutorManager.java b/src/java/azkaban/executor/ExecutorManager.java
index 54c61d5..2c4f941 100644
--- a/src/java/azkaban/executor/ExecutorManager.java
+++ b/src/java/azkaban/executor/ExecutorManager.java
@@ -65,12 +65,12 @@ public class ExecutorManager {
 			}
 		}
 		
-		File activePath = new File(basePath, "active");
+		File activePath = new File(basePath, ".active");
 		if(!activePath.exists() && !activePath.mkdirs()) {
 			throw new RuntimeException("Execution directory " + activePath + " does not exist and cannot be created.");
 		}
 		
-		File archivePath = new File(basePath, "archive");
+		File archivePath = new File(basePath, ".archive");
 		if(!archivePath.exists() && !archivePath.mkdirs()) {
 			throw new RuntimeException("Execution directory " + archivePath + " does not exist and cannot be created.");
 		}
diff --git a/src/java/azkaban/webapp/servlet/velocity/executingflowpage.vm b/src/java/azkaban/webapp/servlet/velocity/executingflowpage.vm
index 6f66fb4..676affe 100644
--- a/src/java/azkaban/webapp/servlet/velocity/executingflowpage.vm
+++ b/src/java/azkaban/webapp/servlet/velocity/executingflowpage.vm
@@ -6,6 +6,7 @@
 		<script type="text/javascript" src="${context}/js/jqueryui/jquery-ui.custom.min.js"></script>   
 		<script type="text/javascript" src="${context}/js/namespace.js"></script>
 		<script type="text/javascript" src="${context}/js/underscore-1.2.1-min.js"></script>
+		<script type="text/javascript" src="${context}/js/azkaban.date.utils.js"></script>
 		<script type="text/javascript" src="${context}/js/backbone-0.5.3-min.js"></script>
 		<script type="text/javascript" src="${context}/js/jquery.simplemodal.js"></script>
 		<script type="text/javascript" src="${context}/js/jquery.contextMenu.js"></script>
@@ -84,6 +85,17 @@
 		</ul>
 
 		</div>
+		<div id="flow-status">
+			<table class="status">
+				<tr><td class="first">Status</td><td id="flowStatus">-</td></tr>
+				<tr><td class="first">Submit User</td><td id="submitUser">-</td></tr>
+			</table>
+			<table class="time">
+				<tr><td class="first">Start Time</td><td id="startTime">-</td></tr>
+				<tr><td class="first">End Time</td><td id="endTime">-</td></tr>
+				<tr><td class="first">Duration</td><td id="duration">-</td></tr>
+			</table>
+		</div>
 	</body>
 </html>
 
diff --git a/src/web/css/azkaban.css b/src/web/css/azkaban.css
index aec8164..d57c62e 100644
--- a/src/web/css/azkaban.css
+++ b/src/web/css/azkaban.css
@@ -1378,6 +1378,66 @@ span.sublabel {
 	background-color: #c7eeff;
 }
 
+#flow-status {
+	position: absolute;
+	top: 115px;
+	right: 55px;
+	width: 420px;
+}
+
+#flow-status table {
+	float: left;
+	border: none;
+	background: none;
+	width: 190px;
+	margin-left: 10px;
+}
+
+#flow-status table.status {
+	width: 200px;
+}
+
+#flow-status table.status td {
+	font-size: 11.5pt;
+}
+
+#flow-status td.first {
+	font-weight: bold;
+}
+
+#flow-status table tr {
+}
+
+#flow-status table td {
+	border: none;
+	padding: 1px;
+	font-size: 12px;
+}
+
+#flow-status table td.SUCCEEDED {
+	color:  #00CC33;
+}
+
+#flow-status table td.RUNNING {
+	color:  #009FC9;
+}
+
+#flow-status table td.FAILED {
+	color:  #CC0000;
+}
+
+#flow-status table td.FAILED_FINISHING {
+	color:  #CC0000;
+}
+
+#flow-status table td.KILLED {
+	color:  #CC0000;
+}
+
+#flowStatus {
+	font-weight: bold;
+}
+
 /* old styles */
 
 .azkaban-charts .hitarea {
diff --git a/src/web/js/azkaban.date.utils.js b/src/web/js/azkaban.date.utils.js
new file mode 100644
index 0000000..2f6f01e
--- /dev/null
+++ b/src/web/js/azkaban.date.utils.js
@@ -0,0 +1,59 @@
+var getDuration = function(startMs, endMs) {
+	if (startMs) {
+		if (endMs == null) {
+			if (data.status == "running") {
+				endMs = currentTime;
+			}
+			else {
+				return "-";
+			}
+		}
+		
+		var diff = endMs - startMs;
+		var seconds = Math.floor(diff / 1000);
+		
+		if (seconds < 60) {
+			return seconds + " sec";
+		}
+		
+		var mins = Math.floor(seconds / 60);
+		seconds = seconds % 60;
+		if (mins < 60) {
+			return mins + "m " + seconds + "s";
+		}
+
+		var hours = Math.floor(mins / 60);
+		mins = mins % 60;
+		if (hours < 24) {
+			return hours + "h " + mins + " m" + seconds + "s";
+		}
+		
+		var days = Math.floor(hours / 24);
+		hours = hours % 24;
+		
+		return days + "d " + hours + "h " + mins + "m " + seconds + "s";
+	}
+
+	return "-";
+}
+
+var getDateFormat = function(date) {
+	var year = date.getFullYear();
+	var month = getTwoDigitStr(date.getMonth());
+	var day = getTwoDigitStr(date.getDate());
+	
+	var hours = getTwoDigitStr(date.getHours());
+	var minutes = getTwoDigitStr(date.getMinutes());
+	var second = getTwoDigitStr(date.getSeconds());
+
+	var datestring = year + "-" + month + "-" + day + "  " + hours + ":" + minutes + " " + second + "s";
+	return datestring;
+}
+
+var getTwoDigitStr = function(value) {
+	if (value < 10) {
+		return "0" + value;
+	}
+	
+	return value;
+}
\ No newline at end of file
diff --git a/src/web/js/azkaban.exflow.view.js b/src/web/js/azkaban.exflow.view.js
index 0bd2f68..1ec6f2a 100644
--- a/src/web/js/azkaban.exflow.view.js
+++ b/src/web/js/azkaban.exflow.view.js
@@ -39,6 +39,61 @@ function removeClass(el, name)
    }
 }
 
+var statusView;
+azkaban.StatusView= Backbone.View.extend({
+	initialize : function(settings) {
+		this.model.bind('change:graph', this.render, this);
+		this.model.bind('change:update', this.statusUpdate, this);
+	},
+	render : function(evt) {
+		var data = this.model.get("data");
+		
+		var user = data.submitUser;
+		$("#submitUser").text(user);
+		
+		this.statusUpdate(evt);
+	},
+	statusUpdate : function(evt) {
+		var data = this.model.get("data");
+		
+		statusItem = $("#flowStatus");
+		for (var j = 0; j < statusList.length; ++j) {
+			var status = statusList[j];
+			statusItem.removeClass(status);
+		}
+		$("#flowStatus").addClass(data.status);
+		$("#flowStatus").text(data.status);
+		
+		var startTime = data.startTime;
+		var endTime = data.endTime;
+		
+		if (startTime == -1) {
+			$("#startTime").text("-");
+		}
+		else {
+			var date = new Date(startTime);
+			$("#startTime").text(getDateFormat(date));
+			
+			var lastTime = endTime;
+			if (endTime == -1) {
+				var currentDate = new Date();
+				lastTime = currentDate.getTime();
+			}
+			
+			var durationString = getDuration(startTime, lastTime);
+			$("#duration").text(durationString);
+		}
+		
+		if (endTime == -1) {
+			$("#endTime").text("-");
+		}
+		else {
+			var date = new Date(endTime);
+			$("#endTime").text(getDateFormat(date));
+		}
+	}
+});
+
 var flowTabView;
 azkaban.FlowTabView= Backbone.View.extend({
   events : {
@@ -511,7 +566,8 @@ var updaterFunction = function() {
 	          updateTime = Math.max(updateTime, data.endTime);
 	          oldData.submitTime = data.submitTime;
 	          oldData.startTime = data.startTime;
-	          oldData.endtime = data.endTime;
+	          oldData.endTime = data.endTime;
+	          oldData.status = data.status;
 	          
 	          for (var i = 0; i < data.nodes.length; ++i) {
 	          	var node = data.nodes[i];
@@ -563,7 +619,7 @@ $(function() {
 	graphModel = new azkaban.GraphModel();
 	svgGraphView = new azkaban.SvgGraphView({el:$('#svgDiv'), model: graphModel});
 	jobsListView = new azkaban.JobListView({el:$('#jobList'), model: graphModel});
-	
+	statusView = new azkaban.StatusView({el:$('#flow-status'), model: graphModel});
 	var requestURL = contextURL + "/executor";
 
 	$.get(
@@ -587,7 +643,7 @@ $(function() {
 	          }
 	          
 	          graphModel.set({nodeMap: nodeMap});
-	      	  setTimeout(function() {updaterFunction()}, 2000);
+	      	  setTimeout(function() {updaterFunction()}, 5000);
 	      },
 	      "json"
 	    );