Преглед изворни кода

Merge pull request #5319 from GordonSmith/HPCC-10758

HPCC-10758 Display all clusters on activity page

Reviewed-By: Miguel Vazquez <miguel.vazquez@lexisnexis.com>
Reviewed-By: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman пре 11 година
родитељ
комит
b89d07dc82

+ 58 - 21
esp/files/scripts/ActivityWidget.js

@@ -28,21 +28,20 @@ define([
     "dgrid/Keyboard",
     "dgrid/Selection",
     "dgrid/selector",
+    "dgrid/tree",
     "dgrid/extensions/ColumnResizer",
     "dgrid/extensions/DijitRegistry",
 
     "hpcc/GridDetailsWidget",
-    "hpcc/ESPWorkunit",
-    "hpcc/ESPDFUWorkunit",
-    "hpcc/WsSMC",
+    "hpcc/ESPActivity",
     "hpcc/WUDetailsWidget",
     "hpcc/DFUWUDetailsWidget",
     "hpcc/ESPUtil"
 
 ], function (declare, lang, i18n, nlsCommon, nlsSpecific, arrayUtil, on,
                 Button,
-                OnDemandGrid, Keyboard, Selection, selector, ColumnResizer, DijitRegistry,
-                GridDetailsWidget, ESPWorkunit, ESPDFUWorkunit, WsSMC, WUDetailsWidget, DFUWUDetailsWidget, ESPUtil) {
+                OnDemandGrid, Keyboard, Selection, selector, tree, ColumnResizer, DijitRegistry,
+                GridDetailsWidget, ESPActivity, WUDetailsWidget, DFUWUDetailsWidget, ESPUtil) {
     return declare("ActivityWidget", [GridDetailsWidget], {
 
         i18n: lang.mixin(nlsCommon, nlsSpecific),
@@ -59,29 +58,70 @@ define([
             if (this.inherited(arguments))
                 return;
 
+            var context = this;
+            this.activity.monitor(function (activity) {
+                context.grid.set("query", {});
+            });
+
             this._refreshActionState();
         },
 
         createGrid: function (domID) {
             var context = this;
+            this.noDataMessage = this.i18n.loadingMessage;
+            this.activity = ESPActivity.Get();
             var retVal = new declare([OnDemandGrid, Keyboard, Selection, ColumnResizer, DijitRegistry, ESPUtil.GridHelper])({
                 allowSelectAll: true,
                 deselectOnRefresh: false,
-                store: WsSMC.CreateActivityStore(),
+                store: this.activity.getStore(),
                 columns: {
-                    col1: selector({ width: 27, selectorType: 'checkbox' }),
-                    Wuid: {
-                        label: this.i18n.ActiveWorkunit, width: 180, sortable: true,
-                        formatter: function (Wuid, row) {
-                            var wu = row.Server === "DFUserver" ? ESPDFUWorkunit.Get(Wuid) : ESPWorkunit.Get(Wuid);
-                            return "<img src='../files/" + wu.getStateImage() + "'>&nbsp;<a href='#' class='" + context.id + "WuidClick'>" + Wuid + "</a>";
+                    col1: selector({
+                        width: 27,
+                        selectorType: 'checkbox',
+                        disabled: function (item) {
+                            if (item.__hpcc_type) {
+                                switch (item.__hpcc_type) {
+                                    case "TargetCluster":
+                                        return true;
+                                }
+                            }
+                            return false;
+                        },
+                        sortable: false
+                    }),
+                    DisplayName: tree({
+                        label: this.i18n.Target,
+                        width: 225,
+                        sortable: true,
+                        shouldExpand: function(row, level, previouslyExpanded) {
+                            return true;
+                        },
+                        formatter: function (_name, row) {
+                            var img = "../files/";
+                            var name = "";
+                            if (row.__hpcc_type === "TargetCluster") {
+                                img += "img/server.png";
+                                name = row.__hpcc_id;
+                            } else {
+                                img += row.getStateImage();
+                                name = "<a href='#' class='" + context.id + "WuidClick'>" + row.Wuid + "</a>";
+                            }
+                            return "<img src='" + img + "'/>&nbsp;" + name;
                         }
-
-                    },
-                    ClusterName: { label: this.i18n.Target, width: 108, sortable: true },
+                    }),
                     State: {
-                        label: this.i18n.State, width: 180, sortable: true, formatter: function (state, row) {
-                            return state + (row.Duration ? " (" + row.Duration + ")" : "");
+                        label: this.i18n.State,
+                        sortable: true,
+                        formatter: function (state, row) {
+                            if (row.__hpcc_type === "TargetCluster") {
+                                return "";
+                            }
+                            if (row.Duration) {
+                                return state + " (" + row.Duration + ")";
+                            } else if (row.Instance && state.indexOf(row.Instance) === -1) {
+                                return state + " [" + row.Instance + "]";
+                            }
+                            return state;
                         }
                     },
                     Owner: { label: this.i18n.Owner, width: 90, sortable: true },
@@ -89,7 +129,6 @@ define([
                 }
             }, domID);
 
-            var context = this;
             on(document, "." + this.id + "WuidClick:click", function (evt) {
                 if (context._onRowDblClick) {
                     var row = retVal.row(evt).data;
@@ -146,9 +185,7 @@ define([
         },
 
         refreshGrid: function (args) {
-            var context = this;
-            this.grid.set("query", {
-            });
+            this.activity.refresh();
         },
 
         refreshActionState: function (selection) {

+ 206 - 0
esp/files/scripts/ESPActivity.js

@@ -0,0 +1,206 @@
+/*##############################################################################
+#    HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems.
+#
+#    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([
+    "dojo/_base/declare",
+    "dojo/_base/array",
+    "dojo/_base/lang",
+    "dojo/store/Memory",
+    "dojo/store/Observable",
+
+    "hpcc/WsSMC",
+    "hpcc/ESPUtil",
+    "hpcc/ESPRequest",
+    "hpcc/ESPWorkunit",
+    "hpcc/ESPDFUWorkunit"
+
+], function (declare, arrayUtil, lang, Memory, Observable,
+    WsSMC, ESPUtil, ESPRequest, ESPWorkunit, ESPDFUWorkunit) {
+
+    var _workunits = {};
+
+    var Store = declare([Memory], {
+        idProperty: "__hpcc_id",
+        mayHaveChildren: function (item) {
+            return (item.children && item.children.length)
+        },
+        getChildren: function (parent, options) {
+            var store = Observable(new Memory({
+                idProperty: "__hpcc_id",
+                parent: parent,
+                _watched: [],
+                data: []
+            }));
+            arrayUtil.forEach(parent.children, function (item, idx) {
+                var wu = item.Server === "DFUserver" ? ESPDFUWorkunit.Get(item.Wuid) : ESPWorkunit.Get(item.Wuid);
+                wu.updateData(item);
+                try {
+                    store.add(wu);
+                    if (!store._watched[item.Wuid]) {
+                        store._watched[item.Wuid] = wu.watch("changedCount", function (name, oldValue, newValue) {
+                            if (oldValue !== newValue) {
+                                store.notify(wu, item.__hpcc_id);
+                            }
+                        });
+                    }
+                } catch (e) {
+                }
+            });
+            return store.query();
+        }
+    });
+
+    var Activity = declare([ESPUtil.Singleton, ESPUtil.Monitor], {
+        //  Asserts  ---
+        _assertHasWuid: function () {
+            if (!this.Wuid) {
+                throw new Error("Wuid cannot be empty.");
+            }
+        },
+        //  Attributes  ---
+        _StateIDSetter: function (StateID) {
+            this.StateID = StateID;
+            var actionEx = lang.exists("ActionEx", this) ? this.ActionEx : null;
+            this.set("hasCompleted", WsWorkunits.isComplete(this.StateID, actionEx));
+        },
+
+        //  ---  ---  ---
+        constructor: function (args) {
+            this.inherited(arguments);
+            this.store = new Store();
+            this.observableStore = new Observable(this.store)
+        },
+        monitor: function (callback) {
+            if (callback && this.changedCount) {
+                callback(this);
+            }
+            if (!this.hasCompleted) {
+                var context = this;
+                this.watch("changedCount", function (name, oldValue, newValue) {
+                    if (oldValue !== newValue && newValue) {
+                        if (callback) {
+                            callback(context);
+                        }
+                    }
+                });
+            }
+        },
+
+        getActivity: function (request) {
+            var context = this;
+            return WsSMC.Activity({
+                request: request
+            }).then(function (response) {
+                if (lang.exists("ActivityResponse", response)) {
+                    context.updateData(response.ActivityResponse);
+
+                    var targetClusters = [];
+                    var targetClusterMap = {};
+                    context.refreshTargetClusters("HThorClusterList.TargetCluster", targetClusters, targetClusterMap);
+                    context.refreshTargetClusters("ThorClusterList.TargetCluster", targetClusters, targetClusterMap);
+                    context.refreshTargetClusters("RoxieClusterList.TargetCluster", targetClusters, targetClusterMap);
+                    context.refreshServerJobQueue("ServerJobQueues.ServerJobQueue", targetClusters, targetClusterMap);
+                    context.refreshActiveWorkunits("Running.ActiveWorkunit", targetClusters, targetClusterMap);
+                    context.store.setData(targetClusters);
+                    context.updateData({
+                        targetClusters: targetClusters
+                    });
+                }
+                return response;
+            });
+        },
+
+        setBanner: function (bannerText) {
+            this.getActivity({
+                FromSubmitBtn: true,
+                BannerAction: bannerText != "",
+                EnableChatURL: 0,
+                BannerContent: bannerText,
+                BannerColor: "red",
+                BannerSize: 4,
+                BannerScroll: 2
+            });
+        },
+
+        refreshTargetClusters: function (targetClusterStr, targetClusters, targetClusterMap) {
+            if (lang.exists(targetClusterStr, this)) {
+                arrayUtil.forEach(lang.getObject(targetClusterStr, false, this), function (item, idx) {
+                    item["__hpcc_type"] = "TargetCluster";
+                    item["__hpcc_id"] = item.ClusterName;
+                    item.children = [];
+                    targetClusters.push(item);
+                    targetClusterMap[item.ClusterName] = item;
+                });
+            }
+        },
+
+        refreshServerJobQueue: function (serverJobQueueStr, targetClusters, targetClusterMap) {
+            if (lang.exists(serverJobQueueStr, this)) {
+                arrayUtil.forEach(lang.getObject(serverJobQueueStr, false, this), function (item, idx) {
+                    item["__hpcc_type"] = "TargetCluster";
+                    item["__hpcc_id"] = item.QueueName;
+                    item.children = [];
+                    targetClusters.push(item);
+                    targetClusterMap[item.QueueName] = item;
+                });
+            }
+        },
+
+        refreshActiveWorkunits: function (activeWorkunitsStr, targetClusters, targetClusterMap) {
+            if (lang.exists(activeWorkunitsStr, this)) {
+                arrayUtil.forEach(lang.getObject(activeWorkunitsStr, false, this), function (item, idx) {
+                    item["__hpcc_id"] = item.Wuid;
+                    targetClusterMap[item.ClusterName ? item.ClusterName : item.QueueName].children.push(item);
+                });
+            }
+        },
+
+        inRefresh: false,
+        refresh: function (full) {
+            var context = this;
+            if (this.inRefresh) {
+                return;
+            }
+            this.inRefresh = true;
+            this.getActivity({
+            }).then(function (response) {
+                context.inRefresh = false;
+            }, function (err) {
+                context.inRefresh = false;
+            });
+        },
+
+        getStore: function () {
+            return this.observableStore;
+        }
+    });
+    var globalActivity = null;
+
+    return {
+        Get: function () {
+            if (!globalActivity) {
+                globalActivity = new Activity;
+                globalActivity.startMonitor();
+                globalActivity.refresh();
+            }
+            return globalActivity;
+        },
+
+        CreateActivityStore: function (options) {
+            var store = new Store(options);
+            return Observable(store);
+        }
+    };
+});

+ 3 - 3
esp/files/scripts/ESPRequest.js

@@ -359,11 +359,11 @@ define([
                     return 0;
                 });
                 Deferred.when(results, function (response) {
+                    if (context.preProcessFullResponse) {
+                        context.preProcessFullResponse(response, request, query, options);
+                    }
                     var items = [];
                     if (context._hasResponseContent(response)) {
-                        if (context.preProcessFullResponse) {
-                            context.preProcessFullResponse(response, request, query, options);
-                        }
                         if (context.preProcessResponse) {
                             var responseQualiferArray = context.responseQualifier.split(".");
                             context.preProcessResponse(lang.getObject(responseQualiferArray[0], false, response), request, query, options);

+ 5 - 2
esp/files/scripts/GridDetailsWidget.js

@@ -96,6 +96,9 @@ define([
         //  Implementation  ---
         initGrid: function() {
             var context = this;
+            this.noDataMessage = this.i18n.noDataMessage;
+            this.loadingMessage = this.i18n.loadingMessage;
+
             var store = new Memory({
                 idProperty: this.idProperty,
                 data: []
@@ -120,10 +123,10 @@ define([
                 context._refreshActionState();
             });
             if (!this.grid.get("noDataMessage")) {
-                this.grid.set("noDataMessage", "<span class='dojoxGridNoData'>" + this.i18n.noDataMessage + "</span>");
+                this.grid.set("noDataMessage", "<span class='dojoxGridNoData'>" + this.noDataMessage + "</span>");
             }
             if (!this.grid.get("loadingMessage")) {
-                this.grid.set("loadingMessage", "<span class='dojoxGridNoData'>" + this.i18n.loadingMessage + "</span>");
+                this.grid.set("loadingMessage", "<span class='dojoxGridNoData'>" + this.loadingMessage + "</span>");
             }
             this.grid.startup();
         },

+ 17 - 26
esp/files/scripts/HPCCPlatformWidget.js

@@ -29,6 +29,7 @@ define([
     "dojox/widget/UpgradeBar",
 
     "hpcc/_TabContainerWidget",
+    "hpcc/ESPActivity",
     "hpcc/WsAccount",
     "hpcc/ws_access",
     "hpcc/WsSMC",
@@ -59,7 +60,7 @@ define([
 ], function (declare, lang, i18n, nlsCommon, nlsSpecific, arrayUtil, dom, domStyle,
                 registry, Tooltip,
                 UpgradeBar,
-                _TabContainerWidget, WsAccount, WsAccess, WsSMC, GraphWidget,
+                _TabContainerWidget, ESPActivity, WsAccount, WsAccess, WsSMC, GraphWidget,
                 template) {
     return declare("HPCCPlatformWidget", [_TabContainerWidget], {
         templateString: template,
@@ -96,6 +97,9 @@ define([
 
         //  Implementation  ---
         parseBuildString: function (build) {
+            if (!build) {
+                return;
+            }
             this.build = {};
             this.build.orig = build;
             this.build.prefix = "";
@@ -112,14 +116,11 @@ define([
             this.build.version = verArray.join("_");
         },
 
-        refreshActivityResponse: function(response) {
-            if (lang.exists("ActivityResponse.Build", response)) {
-                this.parseBuildString(response.ActivityResponse.Build);
-                this.banner = lang.exists("ActivityResponse.BannerContent", response) ? response.ActivityResponse.BannerContent : "";
-                if (this.banner) {
-                    this.upgradeBar.notify("<div style='text-align:center'><b>" + this.banner + "</b></div>");
-                    this.upgradeBar.show();
-                }
+        refreshBanner: function (banner) {
+            if (this.banner !== banner) {
+                this.banner = banner;
+                this.upgradeBar.notify("<div style='text-align:center'><b>" + banner + "</b></div>");
+                this.upgradeBar.show();
             }
         },
 
@@ -137,9 +138,12 @@ define([
                 }
             });
 
-            WsSMC.Activity({
-            }).then(function (response) {
-                context.refreshActivityResponse(response);
+            this.activity = ESPActivity.Get();
+            this.activity.watch("Build", function (name, oldValue, newValue) {
+                context.parseBuildString(newValue);
+            });
+            this.activity.watch("BannerContent", function (name, oldValue, newValue) {
+                context.refreshBanner(newValue);
             });
 
             this.createStackControllerTooltip(this.id + "_ECL", this.i18n.ECL);
@@ -226,20 +230,7 @@ define([
         },
 
         _onSetBannerOk: function (evt) {
-            var context = this;
-            WsSMC.Activity({
-                request: {
-                    FromSubmitBtn: true,
-                    BannerAction: dom.byId(this.id + "BannerText").value != "",
-                    EnableChatURL: 0,
-                    BannerContent: dom.byId(this.id + "BannerText").value,
-                    BannerColor: "red",
-                    BannerSize: 4,
-                    BannerScroll: 2
-                }
-            }).then(function (response) {
-                context.refreshActivityResponse(response);
-            });
+            this.activity.setBanner(dom.byId(this.id + "BannerText").value);
             this.setBannerDialog.hide();
         },
 

+ 3 - 40
esp/files/scripts/WsSMC.js

@@ -15,50 +15,13 @@
 ############################################################################## */
 define([
     "dojo/_base/declare",
-    "dojo/store/Observable",
 
-    "hpcc/ESPRequest",
-    "hpcc/ESPWorkunit",
-    "hpcc/ESPDFUWorkunit"
-], function (declare, Observable,
-    ESPRequest, ESPWorkunit, ESPDFUWorkunit) {
+    "hpcc/ESPRequest"
 
-    var Store = declare([ESPRequest.Store], {
-        service: "WsSMC",
-        action: "Activity",
-        responseQualifier: "ActivityResponse.Running.ActiveWorkunit",
-        idProperty: "Wuid",
-
-        _watched: [],
-        create: function (id, item) {
-            if (item.Server === "DFUserver") {
-                return ESPDFUWorkunit.Get(id);
-            }
-            return ESPWorkunit.Get(id);
-        },
-        update: function (id, item) {
-            var storeItem = this.get(id);
-            storeItem.updateData(item);
-            if (!this._watched[id]) {
-                var context = this;
-                this._watched[id] = storeItem.watch("changedCount", function (name, oldValue, newValue) {
-                    if (context.notify && oldValue !== newValue) {
-                        context.notify(storeItem, id);
-                    }
-                });
-            }
-        },
-        postProcessResults: function (items) {
-            return items;
-        }
-    });
+], function (declare,
+    ESPRequest) {
 
     return {
-        CreateActivityStore: function (options) {
-            var store = new Store(options);
-            return store;//Observable(store);
-        },
-
         Activity: function (params) {
             return ESPRequest.send("WsSMC", "Activity", params);
         }

+ 2 - 2
esp/files/scripts/nls/common.js

@@ -9,8 +9,8 @@ define({ root:
     Filter: "Filter",
     HPCCSystems: "HPCC Systems",
     Loading: "Loading",
-    loadingMessage: "Loading...",
-    noDataMessage: "Zero Rows...",
+    loadingMessage: "...Loading...",
+    noDataMessage: "...Zero Rows...",
     OK: "OK",
     Open: "Open",
     OpenInNewPage: "Open in New Page",