You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ga...@apache.org on 2013/08/05 18:19:14 UTC

git commit: updated refs/heads/master to 3d64428

Updated Branches:
  refs/heads/master c843cef7e -> 3d6442873


Fauxton:  Add Active tasks
View all active tasks with polling interval, Sort in table. filter by
type.


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/3d644287
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/3d644287
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/3d644287

Branch: refs/heads/master
Commit: 3d644287373a4f53ecd817204e3f5fca197f9a19
Parents: c843cef
Author: suelockwood <de...@gmail.com>
Authored: Fri Jul 26 13:53:16 2013 -0400
Committer: Garren Smith <ga...@gmail.com>
Committed: Mon Aug 5 18:18:47 2013 +0200

----------------------------------------------------------------------
 .gitignore                                      |   1 +
 .../activetasks/assets/less/activetasks.less    |   4 +
 src/fauxton/app/addons/activetasks/base.js      |  26 +++
 src/fauxton/app/addons/activetasks/resources.js | 108 ++++++++++++
 src/fauxton/app/addons/activetasks/routes.js    |  52 ++++++
 .../addons/activetasks/templates/detail.html    |  21 +++
 .../app/addons/activetasks/templates/table.html |  52 ++++++
 .../activetasks/templates/tabledetail.html      |  36 ++++
 .../app/addons/activetasks/templates/tabs.html  |  28 ++++
 src/fauxton/app/addons/activetasks/views.js     | 165 +++++++++++++++++++
 src/fauxton/app/helpers.js                      |   5 +
 src/fauxton/assets/less/database.less           |   6 +
 src/fauxton/assets/less/fauxton.less            |   2 +
 src/fauxton/settings.json.default               |   1 +
 14 files changed, 507 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/3d644287/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index c1ece09..43d4773 100644
--- a/.gitignore
+++ b/.gitignore
@@ -87,6 +87,7 @@ src/fauxton/build
 src/fauxton/app/load_addons.js
 !src/fauxton/app/addons/
 src/fauxton/app/addons/*
+!src/fauxton/app/addons/activetasks
 !src/fauxton/app/addons/config
 !src/fauxton/app/addons/logs
 !src/fauxton/app/addons/stats

http://git-wip-us.apache.org/repos/asf/couchdb/blob/3d644287/src/fauxton/app/addons/activetasks/assets/less/activetasks.less
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/activetasks/assets/less/activetasks.less b/src/fauxton/app/addons/activetasks/assets/less/activetasks.less
new file mode 100644
index 0000000..5cb9d47
--- /dev/null
+++ b/src/fauxton/app/addons/activetasks/assets/less/activetasks.less
@@ -0,0 +1,4 @@
+.task-tabs li {
+  cursor: pointer;
+  padding: 5px 0;
+}

http://git-wip-us.apache.org/repos/asf/couchdb/blob/3d644287/src/fauxton/app/addons/activetasks/base.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/activetasks/base.js b/src/fauxton/app/addons/activetasks/base.js
new file mode 100644
index 0000000..c7b8fb0
--- /dev/null
+++ b/src/fauxton/app/addons/activetasks/base.js
@@ -0,0 +1,26 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+define([
+  "app",
+  "api",
+  "addons/activetasks/routes"
+],
+
+function (app, FauxtonAPI, Activetasks) {
+
+  Activetasks.initialize = function() {
+    FauxtonAPI.addHeaderLink({title: "Active Tasks", href: "#/activetasks"});
+  };
+ 
+  return Activetasks;
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/3d644287/src/fauxton/app/addons/activetasks/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/activetasks/resources.js b/src/fauxton/app/addons/activetasks/resources.js
new file mode 100644
index 0000000..6d892dd
--- /dev/null
+++ b/src/fauxton/app/addons/activetasks/resources.js
@@ -0,0 +1,108 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+define([
+  "app",
+  "backbone",
+  "modules/fauxton/base",
+  "d3"
+],
+
+function (app, backbone, Fauxton) {
+  var Active = {},
+      apiv = app.versionAPI;
+      app.taskSortBy = 'type';
+
+  Active.Task = Backbone.Model.extend({
+    initialize: function() { 
+      this.set({"id": this.get('pid')});
+    }
+  });
+
+// ALL THE TASKS
+  Active.Tasks = Backbone.Model.extend({
+    alltypes: {
+      "all": "All tasks",
+      "replication": "Replication",
+      "database_compaction":" Database Compaction",
+      "indexer": "Indexer",
+      "view_compaction": "View Compaction"
+    },
+    url: function () {
+      return app.host + '/_active_tasks';
+    },
+    parse: function(resp){
+      var types = this.getUniqueTypes(resp),
+          that = this;
+
+      var typeCollections = _.reduce(types, function (collection, val, key) {
+          collection[key] = new Active.AllTasks(that.sortThis(resp, key));
+          return collection;
+        }, {});
+
+      typeCollections.all = new Active.AllTasks(resp);
+
+      this.set(typeCollections);  //now set them all to the model
+    },
+    getUniqueTypes: function(resp){
+      var types = this.alltypes;
+
+      _.each(resp, function(type){
+        if( typeof(types[type.type]) === "undefined"){
+          types[type.type] = type.type.replace(/_/g,' ');
+        }
+      },this);
+
+      this.alltypes = types;
+      return types;
+    },
+    sortThis: function(resp, type){
+      return _.filter(resp, function(item) { return item.type === type; });
+    },
+    changeView: function (view){
+      this.set({
+        "currentView": view
+      });
+    },
+    getCurrentViewData: function(){
+      var currentView = this.get('currentView');
+      return this.get(currentView);
+    },
+    getDatabaseCompactions: function(){
+      return this.get('databaseCompactions');
+    },
+    getIndexes: function(){
+      return this.get('indexes');
+    },
+    getViewCompactions: function(){
+      return this.get('viewCompactions');
+    }
+  });
+
+//ALL TASKS
+
+//NEW IDEA. Lets make this extremely generic, so if there are new weird tasks, they get sorted and collected.
+
+  Active.AllTasks = Backbone.Collection.extend({
+    model: Active.Task,
+    sortByColumn: function(colName) {
+      app.taskSortBy = colName;
+      this.sort();
+    },
+    comparator: function(item) {
+      return item.get(app.taskSortBy);
+    }
+  });
+
+
+  return Active;
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/3d644287/src/fauxton/app/addons/activetasks/routes.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/activetasks/routes.js b/src/fauxton/app/addons/activetasks/routes.js
new file mode 100644
index 0000000..027beee
--- /dev/null
+++ b/src/fauxton/app/addons/activetasks/routes.js
@@ -0,0 +1,52 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+define([
+  "app",
+  "api",
+  "addons/activetasks/resources",
+  "addons/activetasks/views"
+],
+
+function (app, FauxtonAPI, Activetasks, Views) {
+
+  var  ActiveTasksRouteObject = FauxtonAPI.RouteObject.extend({
+    layout: "with_sidebar",
+    routes: {
+      "activetasks/:id": "defaultView",
+      "activetasks": "defaultView"
+    },
+    crumbs: [],
+    apiUrl: function(){
+      return app.host+"/_active_tasks";
+    }, 
+    defaultView: function(id){
+      var newtasks = new Activetasks.Tasks({
+        currentView: "all", 
+        id:'activeTasks'
+      });
+      this.setView("#sidebar-content", new Views.TabMenu({
+        currentView: "all",
+        model: newtasks
+      })); 
+
+      this.setView("#dashboard-content", new Views.DataSection({
+        model: newtasks,
+        currentView: "all"
+      })); 
+    }
+  });
+
+  Activetasks.RouteObjects = [ActiveTasksRouteObject];
+
+  return Activetasks;
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/3d644287/src/fauxton/app/addons/activetasks/templates/detail.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/activetasks/templates/detail.html b/src/fauxton/app/addons/activetasks/templates/detail.html
new file mode 100644
index 0000000..5e53129
--- /dev/null
+++ b/src/fauxton/app/addons/activetasks/templates/detail.html
@@ -0,0 +1,21 @@
+<!--
+Licensed under the Apache License, Version 2.0 (the "License"); you may not
+use this file except in compliance with the License. You may obtain a copy of
+the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+License for the specific language governing permissions and limitations under
+the License.
+-->
+
+<div class="progress progress-striped active">
+  <div class="bar" style="width: <%=model.get("progress")%>%;"><%=model.get("progress")%>%</div>
+</div>
+<p>
+	<%= model.get("type").replace('_',' ')%> on
+	<%= model.get("node")%>
+</p>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/3d644287/src/fauxton/app/addons/activetasks/templates/table.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/activetasks/templates/table.html b/src/fauxton/app/addons/activetasks/templates/table.html
new file mode 100644
index 0000000..ee88e75
--- /dev/null
+++ b/src/fauxton/app/addons/activetasks/templates/table.html
@@ -0,0 +1,52 @@
+<!--
+Licensed under the Apache License, Version 2.0 (the "License"); you may not
+use this file except in compliance with the License. You may obtain a copy of
+the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+License for the specific language governing permissions and limitations under
+the License.
+-->
+
+<!--
+Licensed under the Apache License, Version 2.0 (the "License"); you may not
+use this file except in compliance with the License. You may obtain a copy of
+the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+License for the specific language governing permissions and limitations under
+the License.
+-->
+
+<% if (collection.length === 0){%>
+   <tr> 
+    <td>
+      <p>There are no active tasks for <%=currentView%> right now.</p>
+    </td>
+  </tr>
+<%}else{%>
+
+  <thead>
+    <tr>
+      <th data-type="type">Type</th>
+      <th data-type="node">Object</th>
+      <th data-type="started_on">Started on</th>
+      <th data-type="updated_on">Last updated on</th>
+      <th data-type="pid">PID</th>
+      <th data-type="progress" width="200">Status</th>
+    </tr>
+  </thead>
+
+  <tbody id="tasks_go_here">
+
+  </tbody>
+
+<% } %>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/3d644287/src/fauxton/app/addons/activetasks/templates/tabledetail.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/activetasks/templates/tabledetail.html b/src/fauxton/app/addons/activetasks/templates/tabledetail.html
new file mode 100644
index 0000000..67c0dc8
--- /dev/null
+++ b/src/fauxton/app/addons/activetasks/templates/tabledetail.html
@@ -0,0 +1,36 @@
+<!--
+Licensed under the Apache License, Version 2.0 (the "License"); you may not
+use this file except in compliance with the License. You may obtain a copy of
+the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+License for the specific language governing permissions and limitations under
+the License.
+-->
+
+<td>
+  <%= model.get("type")%>
+</td>
+<td>
+  <%= objectField %>
+</td>
+<td>
+  <%= formatDate(model.get("started_on")) %>
+</td>
+<td>
+  <%= formatDate(model.get("updated_on")) %>
+</td>
+<td>
+  <%= model.get("pid")%>
+</td>
+<td>
+	<div class="progress progress-striped active">
+	  <div class="bar" style="width: <%=model.get("progress")%>%;"><%=model.get("progress")%>%</div>
+
+	</div>
+	<p><%=progress%> </p>
+</td>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/3d644287/src/fauxton/app/addons/activetasks/templates/tabs.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/activetasks/templates/tabs.html b/src/fauxton/app/addons/activetasks/templates/tabs.html
new file mode 100644
index 0000000..47c5843
--- /dev/null
+++ b/src/fauxton/app/addons/activetasks/templates/tabs.html
@@ -0,0 +1,28 @@
+<!--
+Licensed under the Apache License, Version 2.0 (the "License"); you may not
+use this file except in compliance with the License. You may obtain a copy of
+the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+License for the specific language governing permissions and limitations under
+the License.
+-->
+
+<h3>Filter by: </h3>
+<ul class="task-tabs nav nav-tabs nav-stacked">
+  <% for (var filter in filters) { %>
+      <li data-type="<%=filter%>"><%=filters[filter]%></li>
+  <% } %>
+</ul>
+
+<h4>Polling interval</h4>
+<input id="pollingRange" type="range"
+       min="1"
+       max="30"
+       step="1"
+       value="5"/>
+<label for="pollingRange"><span>5</span> second(s)</label>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/3d644287/src/fauxton/app/addons/activetasks/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/activetasks/views.js b/src/fauxton/app/addons/activetasks/views.js
new file mode 100644
index 0000000..f38aea2
--- /dev/null
+++ b/src/fauxton/app/addons/activetasks/views.js
@@ -0,0 +1,165 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+define([
+  "app",
+  "api",
+  "addons/activetasks/resources"
+],
+
+function (app, FauxtonAPI, activetasks) {
+
+  var Views = {},
+			Events = {},
+			pollingInfo ={
+				rate: "5",
+				intervalId: null
+			};
+
+
+	_.extend(Events, Backbone.Events);
+
+	Views.TabMenu = FauxtonAPI.View.extend({
+		template: "addons/activetasks/templates/tabs",
+		events: {
+			"click .task-tabs li": "requestByType",
+			"change #pollingRange": "changePollInterval"
+		},
+		establish: function(){
+			return [this.model.fetch({reset: true})];
+		},
+		serialize: function(){
+			return {
+				filters: this.model.alltypes
+			};
+		},
+		afterRender: function(){
+			$('.task-tabs').find('li').eq(0).addClass('active');
+		},
+		changePollInterval: function(e){
+			var range = $(e.currentTarget).val();
+			$('label[for="pollingRange"] span').text(range);
+			pollingInfo.rate = range;
+			clearInterval(pollingInfo.intervalId);
+			Events.trigger('update:poll');
+		},
+		requestByType: function(e){
+			var currentTarget = e.currentTarget;
+					datatype = $(currentTarget).attr("data-type");
+
+			$('.task-tabs').find('li').removeClass('active');
+			$(currentTarget).addClass('active');
+			this.model.changeView(datatype);
+		}
+	});
+
+	Views.DataSection = FauxtonAPI.View.extend({
+		initialize: function(){
+			this.listenToOnce(this.model, "change", this.showData); //check why I needed to do this
+		},
+		showData: function(){
+			var that = this,
+					currentData = this.model.getCurrentViewData();
+			//remove the old stuff in a nice clean way
+			if (this.dataView) {
+				this.dataView.remove();
+			}
+
+				//add the new stuff
+			this.dataView = that.insertView( new Views.tableData({ 
+				collection: currentData,
+				currentView: this.model.get('currentView').replace('_',' ')
+			}));
+
+			this.dataView.render();
+		},
+		establish: function(){
+			return [this.model.fetch()];
+		},
+		setPolling: function(){
+			var that = this;
+			pollingInfo.intervalId = setInterval(function() {
+				that.establish();
+			}, pollingInfo.rate*1000);
+		},
+		afterRender: function(){
+			this.listenTo(this.model, "change", this.showData);
+			Events.bind('update:poll', this.setPolling, this);
+			this.setPolling();
+		}
+	});
+
+	Views.tableData = FauxtonAPI.View.extend({
+		tagName: "table",
+		className: "table table-bordered table-striped active-tasks",
+		template: "addons/activetasks/templates/table",
+		events: {
+			"click th": "sortByType"
+		},
+		initialize: function(){
+			currentView = this.options.currentView;
+		},
+		sortByType:  function(e){
+			var currentTarget = e.currentTarget;
+					datatype = $(currentTarget).attr("data-type");
+			this.collection.sortByColumn(datatype);
+			this.render();
+		},
+		serialize: function(){
+			return {
+				currentView: currentView,
+				collection: this.collection
+			};
+		},
+		beforeRender: function(){
+			//iterate over the collection to add each
+			this.collection.forEach(function(item) {
+				this.insertView("#tasks_go_here", new Views.TableDetail({ 
+					model: item
+				}));
+			}, this);
+		}
+	});
+
+	Views.TableDetail = FauxtonAPI.View.extend({
+		tagName: 'tr',
+		template: "addons/activetasks/templates/tabledetail",
+		initialize: function(){
+			this.type = this.model.get('type');
+		},
+		getObject: function(){
+			var objectField = this.model.get('database');
+			if (this.type === "replication"){
+				objectField = this.model.get('source') + " to " + this.model.get('target');
+			}
+			return objectField;
+		},
+		getProgress:  function(){
+			var progress = "";
+			if (this.type === "indexer"){
+				progress = "Processed " +this.model.get('changes_done')+ " of "+this.model.get('total_changes')+ ' changes';
+			}
+			return progress;
+		},
+		serialize: function(){
+			return {
+				model: this.model,
+				objectField: this.getObject(),
+				progress: this.getProgress()
+			};
+		}
+	});
+
+
+ 
+  return Views;
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/3d644287/src/fauxton/app/helpers.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/helpers.js b/src/fauxton/app/helpers.js
index 2ffe2fd..6408afc 100644
--- a/src/fauxton/app/helpers.js
+++ b/src/fauxton/app/helpers.js
@@ -19,6 +19,7 @@
 
 
 define([
+  "d3"
 ],
 
 function() {
@@ -43,6 +44,10 @@ function() {
       return size.toFixed(1) + ' ' + units[i - 1];
     };
 
+  Helpers.formatDate = function(timestamp){
+    format = d3.time.format("%b. %e at %H:%M%p"); 
+    return format(new Date(timestamp*1000));
+  };
 
   return Helpers;
 });

http://git-wip-us.apache.org/repos/asf/couchdb/blob/3d644287/src/fauxton/assets/less/database.less
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/less/database.less b/src/fauxton/assets/less/database.less
index 4ce41f8..b96e730 100644
--- a/src/fauxton/assets/less/database.less
+++ b/src/fauxton/assets/less/database.less
@@ -166,3 +166,9 @@
   padding-right: 10px;
   float: right;
 }
+
+table.active-tasks{
+    th {
+        cursor: pointer;
+    }
+}

http://git-wip-us.apache.org/repos/asf/couchdb/blob/3d644287/src/fauxton/assets/less/fauxton.less
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/less/fauxton.less b/src/fauxton/assets/less/fauxton.less
index 445b815..cef1638 100644
--- a/src/fauxton/assets/less/fauxton.less
+++ b/src/fauxton/assets/less/fauxton.less
@@ -98,3 +98,5 @@ pre.view-code-error {
   background: url('../img/loader.gif') center center no-repeat;
   min-height:  100px;
 }
+
+

http://git-wip-us.apache.org/repos/asf/couchdb/blob/3d644287/src/fauxton/settings.json.default
----------------------------------------------------------------------
diff --git a/src/fauxton/settings.json.default b/src/fauxton/settings.json.default
index 910488b..2b7fe89 100644
--- a/src/fauxton/settings.json.default
+++ b/src/fauxton/settings.json.default
@@ -1,5 +1,6 @@
 {
   "deps": [
+  { "name": "activetasks" },
   { "name": "config" },
   { "name": "logs" },
   { "name": "stats" },