diff --git a/modules/ui/app/plugins/traffic-analysis/ctrl.js b/modules/ui/app/plugins/traffic-analysis/ctrl.js
index 91f31dd0e..d45ff8193 100644
--- a/modules/ui/app/plugins/traffic-analysis/ctrl.js
+++ b/modules/ui/app/plugins/traffic-analysis/ctrl.js
@@ -2,8 +2,8 @@
'use strict';
angular.module('wasabi.controllers').
- controllerProvider.register('TrafficAnalysisCtrl', ['$scope', '$rootScope', 'UtilitiesFactory', '$modalInstance', 'ApplicationsFactory', 'MutualExclusionsFactory', 'PrioritiesFactory', 'ExperimentsFactory', '$cookies',
- function ($scope, $rootScope, UtilitiesFactory, $modalInstance, ApplicationsFactory, MutualExclusionsFactory, PrioritiesFactory, ExperimentsFactory, $cookies) {
+ controllerProvider.register('TrafficAnalysisCtrl', ['$scope', '$rootScope', 'UtilitiesFactory', '$modalInstance', 'ApplicationsFactory', 'MutualExclusionsFactory', 'PrioritiesFactory', 'ExperimentsFactory', '$cookies', 'TrafficManagementShared',
+ function ($scope, $rootScope, UtilitiesFactory, $modalInstance, ApplicationsFactory, MutualExclusionsFactory, PrioritiesFactory, ExperimentsFactory, $cookies, TrafficManagementShared) {
$scope.data = {
applicationName: ($cookies.wasabiDefaultApplication ? $cookies.wasabiDefaultApplication : ''),
selectedExperiment: '',
@@ -15,6 +15,7 @@ angular.module('wasabi.controllers').
$scope.experiments = [];
$scope.experimentNames = [];
+ $scope.columnNames = [];
$scope.relatedExperiments = [];
$scope.priorities = [];
$scope.meDoneNames = [];
@@ -30,7 +31,7 @@ angular.module('wasabi.controllers').
$scope.currentApplicationName = '';
$scope.priorities = [];
$scope.experiments = [];
- $scope.experimentNames = [];
+ $scope.columnNames = [];
$scope.relatedExperiments = [];
$scope.mutualExclusions = {};
};
@@ -84,61 +85,13 @@ angular.module('wasabi.controllers').
}
else {
UtilitiesFactory.displayPageError('Problem Getting Experiments', 'There was a problem retrieving the priorities for the experiment with label, ' + exp.label);
- // TODO: Handle aborting?
return false;
}
return true;
};
$scope.getMutualExclusions = function(exp) {
- console.log('Getting MEs for ' + exp.label);
- MutualExclusionsFactory.query({
- experimentId: exp.id,
- exclusiveFlag: true
- }).$promise.then(function (meExperiments) {
- // Keep track of the mutual exclusions for each experiment so we can calculate the
- // sampling percentages that are effected by the mutual exclusions.
- $scope.mutualExclusions[exp.label] = meExperiments;
- meExperiments.forEach(function(nextExp) {
- $scope.setPriorityOnExperiment(nextExp);
- });
-
- // Add all of the meExperiments that are not already there to the relatedExperiments array
- for (var i = 0; i < meExperiments.length; i++) {
- // Check if it is already in there
- var expSearch = $scope.relatedExperiments.filter(function(exp) {
- return exp.label === meExperiments[i].label;
- });
- if (expSearch.length <= 0) {
- // Add it to the array
- console.log('Adding ' + meExperiments[i].label + ' to relatedExperiments');
- $scope.relatedExperiments.push(meExperiments[i]);
- }
- }
-
- // The priority field from the priorities was added to the
- // mutual exclusion list when we saved it off above. This will
- // allow us to sort by it.
- $scope.relatedExperiments.sort(function (a, b) {
- return a.priority > b.priority;
- });
-
- $scope.meDoneNames.push(exp.label);
- if ($scope.meDoneNames.length === $scope.relatedExperiments.length) {
- console.log('*** We have processed all the mutual exclusions');
- $scope.calculate();
- }
- else {
- meExperiments.forEach(function(nextExp) {
- if ($scope.meDoneNames.indexOf(nextExp.label) < 0) {
- // Only do this one if we haven't already done it (avoid indefinite loop!)
- $scope.getMutualExclusions(nextExp);
- }
- });
- }
- }, function(response) {
- UtilitiesFactory.handleGlobalError(response, 'The mutual exclusions could not be retrieved.');
- });
+ TrafficManagementShared.getMutualExclusions(exp, $scope, $scope.calculate);
};
$scope.initialExperimentSelected = function() {
@@ -153,7 +106,6 @@ angular.module('wasabi.controllers').
$scope.meDoneNames = [];
$scope.mutualExclusions = {};
- //console.dir($scope.data.selectedExperiment);
var expSearch = $scope.experiments.filter(function(exp) {
return exp.label === $scope.data.selectedExperiment;
});
@@ -168,16 +120,15 @@ angular.module('wasabi.controllers').
start: startTime,
end: endTime
}).$promise.then(function(results) {
- $scope.experimentNames = ['Experiments:'];
+ $scope.columnNames = ['Experiments:'];
$scope.dataRows = [
['Priority'],
- //['Target %'],
['Experiment %']
];
var i = 0;
if (results.experiments) {
for (i = 0; i < results.experiments.length; i++) {
- $scope.experimentNames.push(results.experiments[i]);
+ $scope.columnNames.push(results.experiments[i]);
}
}
for (i = 0; i < results.priorities.length; i++) {
@@ -192,6 +143,12 @@ angular.module('wasabi.controllers').
$scope.dataRows.push(row);
}
+ // Prepare the structure used by TrafficManagementShared.getMutualExclusions() to keep track of which
+ // experiments we've gotten the mutual exclusions for.
+ $scope.pendingMEs = [{
+ label: expSearch[0].label,
+ processed: false
+ }];
// Get the mutual exclusions data and then use that to calculate the target sampling %s
$scope.getMutualExclusions($scope.relatedExperiments[0]);
@@ -205,32 +162,7 @@ angular.module('wasabi.controllers').
$scope.calculate = function() {
// Note that the experiments are listed in priority order.
-
- for (var j = 0; j < $scope.relatedExperiments.length; j++) {
- var currentExp = $scope.relatedExperiments[j], mutexs, targetSamplingPercentages;
- if (j === 0) {
- // Highest priority experiment, message will be different.
- currentExp.targetSamplingPercent = currentExp.samplingPercent.toFixed(4);
- }
- else {
- // For all others, we need to calculate the target sampling percentage by looking at the higher
- // priority experiments.
- mutexs = $scope.mutualExclusions[currentExp.label];
- targetSamplingPercentages = 0.0;
-
- for (var k = 0; k < mutexs.length; k++) {
- if (mutexs[k].priority < currentExp.priority) {
- // Get the value the user entered for this mutually exclusive experiment
- var relExp = $scope.relatedExperiments.filter(function(nextExp) {
- return nextExp.label === mutexs[k].label;
- });
- targetSamplingPercentages += parseFloat(relExp[0].targetSamplingPercent);
- }
- }
- var newTargetSamp = parseFloat(currentExp.samplingPercent) * (1 - targetSamplingPercentages);
- currentExp.targetSamplingPercent = parseFloat(newTargetSamp.toFixed(4));
- }
- }
+ // Also note that this function is called after we have calculated the target sampling percentages.
var targets = ['Target %'];
for (var i = 0; i < $scope.relatedExperiments.length; i++) {
targets[i + 1] = $scope.multiply100($scope.relatedExperiments[i].targetSamplingPercent) + '%';
diff --git a/modules/ui/app/plugins/traffic-analysis/template.html b/modules/ui/app/plugins/traffic-analysis/template.html
index c57f577ac..59b67b80b 100644
--- a/modules/ui/app/plugins/traffic-analysis/template.html
+++ b/modules/ui/app/plugins/traffic-analysis/template.html
@@ -63,7 +63,7 @@
Traffic Analyzer
-
{{name}}
+
{{name}}
diff --git a/modules/ui/app/plugins/traffic-management-shared/ctrl.js b/modules/ui/app/plugins/traffic-management-shared/ctrl.js
new file mode 100644
index 000000000..cb6c4edcb
--- /dev/null
+++ b/modules/ui/app/plugins/traffic-management-shared/ctrl.js
@@ -0,0 +1,109 @@
+'use strict';
+
+// This is code shared by the different Traffic Management plugins. It is registered as a service when the app loads.
+// It can then be injected into the plugin controllers.
+angular.module('wasabi.services').
+ provide.factory('TrafficManagementShared', ['UtilitiesFactory', 'MutualExclusionsFactory',
+ function (UtilitiesFactory, MutualExclusionsFactory) {
+ return {
+ calculateTargetSamplingPercentages: function(scope) {
+ for (var j = 0; j < scope.relatedExperiments.length; j++) {
+ var currentExp = scope.relatedExperiments[j], mutexs, targetSamplingPercentages;
+ if (j === 0) {
+ // Highest priority experiment, message will be different.
+ currentExp.targetSamplingPercent = currentExp.samplingPercent.toFixed(4);
+ }
+ else {
+ // For all others, we need to calculate the target sampling percentage by looking at the higher
+ // priority experiments.
+ mutexs = scope.mutualExclusions[currentExp.label];
+ targetSamplingPercentages = 0.0;
+
+ for (var k = 0; k < mutexs.length; k++) {
+ if (mutexs[k].priority < currentExp.priority) {
+ // Get the value the user entered for this mutually exclusive experiment
+ var relExp = scope.relatedExperiments.filter(function(nextExp) {
+ return nextExp.label === mutexs[k].label;
+ });
+ targetSamplingPercentages += parseFloat(relExp[0].targetSamplingPercent);
+ }
+ }
+ var newTargetSamp = parseFloat(currentExp.samplingPercent) * (1 - targetSamplingPercentages);
+ currentExp.targetSamplingPercent = parseFloat(newTargetSamp.toFixed(4));
+ }
+ }
+ },
+
+ getMutualExclusions: function(exp, scope, afterFunc) {
+ var that = this;
+
+ MutualExclusionsFactory.query({
+ experimentId: exp.id,
+ exclusiveFlag: true
+ }).$promise.then(function (meExperiments) {
+ // Keep track of the mutual exclusions for each experiment so we can calculate the
+ // sampling percentages that are effected by the mutual exclusions.
+ scope.mutualExclusions[exp.label] = meExperiments;
+
+ // Add all of the meExperiments that are not already there to the relatedExperiments array
+ for (var i = 0; i < meExperiments.length; i++) {
+ // Perform some housekeeping on each ME
+ scope.setPriorityOnExperiment(meExperiments[i]);
+ meExperiments[i].hoverContent = 'Hi There More stuff is here...';
+
+ // Check if it is already in there
+ var expSearch = scope.relatedExperiments.filter(function(exp) {
+ return exp.label === meExperiments[i].label;
+ });
+ if (expSearch.length <= 0) {
+ // Add it to the array
+ scope.relatedExperiments.push(meExperiments[i]);
+
+ // This experiment was not already in the list, so get its MEs.
+ scope.pendingMEs.push({
+ label: meExperiments[i].label,
+ processed: false
+ });
+ scope.getMutualExclusions(meExperiments[i]);
+ }
+ }
+
+ // Mark that we have completed the process of getting the MEs for this experiment
+ // and check if there are any in the list that are unprocessed. This allows us to know
+ // when we are done processing all the MEs for all the related experiments.
+ var leftUnprocessed = false;
+ for (var j = 0; j < scope.pendingMEs.length; j++) {
+ if (scope.pendingMEs[j].label === exp.label) {
+ scope.pendingMEs[j].processed = true;
+ }
+ else if (!scope.pendingMEs[j].processed) {
+ leftUnprocessed = true;
+ }
+ }
+
+ if (!leftUnprocessed) {
+ // We have processed all the mutual exclusions
+
+ // The priority field from the priorities was added to the
+ // mutual exclusion list when we saved it off above. This will
+ // allow us to sort by it.
+ scope.relatedExperiments.sort(function (a, b) {
+ return a.priority > b.priority;
+ });
+
+ // We always want to determine the target sampling percentages from the priorities,
+ // mutual exclusions and experiment sampling percentages.
+ that.calculateTargetSamplingPercentages(scope);
+
+ if (afterFunc !== undefined) {
+ // Call the function to continue once we have retrieved all the mutual exclusions
+ afterFunc();
+ }
+ }
+ }, function(response) {
+ UtilitiesFactory.handleGlobalError(response, 'The mutual exclusions could not be retrieved.');
+ });
+ }
+ }
+ }
+]);
diff --git a/modules/ui/app/plugins/traffic-management/ctrl.js b/modules/ui/app/plugins/traffic-management/ctrl.js
index 90f2e1451..ee611b736 100644
--- a/modules/ui/app/plugins/traffic-management/ctrl.js
+++ b/modules/ui/app/plugins/traffic-management/ctrl.js
@@ -1,8 +1,8 @@
'use strict';
angular.module('wasabi.controllers').
- controllerProvider.register('TrafficManagementCtrl', ['$scope', '$rootScope', 'UtilitiesFactory', '$modalInstance', 'ApplicationsFactory', 'MutualExclusionsFactory', 'PrioritiesFactory', 'ExperimentsFactory', '$cookies',
- function ($scope, $rootScope, UtilitiesFactory, $modalInstance, ApplicationsFactory, MutualExclusionsFactory, PrioritiesFactory, ExperimentsFactory, $cookies) {
+ controllerProvider.register('TrafficManagementCtrl', ['$scope', '$rootScope', 'UtilitiesFactory', '$modalInstance', 'ApplicationsFactory', 'MutualExclusionsFactory', 'PrioritiesFactory', 'ExperimentsFactory', '$cookies', 'TrafficManagementShared',
+ function ($scope, $rootScope, UtilitiesFactory, $modalInstance, ApplicationsFactory, MutualExclusionsFactory, PrioritiesFactory, ExperimentsFactory, $cookies, TrafficManagementShared) {
$scope.data = {
applicationName: ($cookies.wasabiDefaultApplication ? $cookies.wasabiDefaultApplication : ''),
selectedExperiment: ''
@@ -14,7 +14,6 @@ angular.module('wasabi.controllers').
$scope.experimentNames = [];
$scope.relatedExperiments = [];
$scope.priorities = [];
- $scope.meDoneNames = [];
$scope.mutualExclusions = {};
$scope.numPendingSaves = 0;
@@ -84,116 +83,45 @@ angular.module('wasabi.controllers').
if (exp.samplingPercent) {
exp.originalSamplingPercent = exp.samplingPercent;
exp.targetSamplingPercent = 0;
+ exp.oldSamplingPercent = '';
}
}
else {
UtilitiesFactory.displayPageError('Problem Getting Experiments', 'There was a problem retrieving the priorities for the experiment with label, ' + exp.label);
- // TODO: Handle aborting?
return false;
}
return true;
};
$scope.getMutualExclusions = function(exp) {
- console.log('Getting MEs for ' + exp.label);
- MutualExclusionsFactory.query({
- experimentId: exp.id,
- exclusiveFlag: true
- }).$promise.then(function (meExperiments) {
- // Keep track of the mutual exclusions for each experiment so we can calculate the
- // sampling percentages that are effected by the mutual exclusions.
- $scope.mutualExclusions[exp.label] = meExperiments;
- meExperiments.forEach(function(nextExp) {
- $scope.setPriorityOnExperiment(nextExp);
- nextExp.hoverContent = 'Hi There More stuff is here...';
- });
-
- // Add all of the meExperiments that are not already there to the relatedExperiments array
- for (var i = 0; i < meExperiments.length; i++) {
- // Check if it is already in there
- var expSearch = $scope.relatedExperiments.filter(function(exp) {
- return exp.label === meExperiments[i].label;
- });
- if (expSearch.length <= 0) {
- // Add it to the array
- console.log('Adding ' + meExperiments[i].label + ' to relatedExperiments');
- $scope.relatedExperiments.push(meExperiments[i]);
- }
- }
-
- // The priority field from the priorities was added to the
- // mutual exclusion list when we saved it off above. This will
- // allow us to sort by it.
- $scope.relatedExperiments.sort(function (a, b) {
- return a.priority > b.priority;
- });
-
- $scope.meDoneNames.push(exp.label);
- if ($scope.meDoneNames.length === $scope.relatedExperiments.length) {
- console.log('*** We have processed all the mutual exclusions');
- $scope.calculateTargetSamplingPercentages();
- }
- else {
- meExperiments.forEach(function(nextExp) {
- if ($scope.meDoneNames.indexOf(nextExp.label) < 0) {
- // Only do this one if we haven't already done it (avoid indefinite loop!)
- $scope.getMutualExclusions(nextExp);
- }
- });
- }
- }, function(response) {
- UtilitiesFactory.handleGlobalError(response, 'The mutual exclusions could not be retrieved.');
- });
+ TrafficManagementShared.getMutualExclusions(exp, $scope);
};
- $scope.calculateTargetSamplingPercentages = function() {
- for (var j = 0; j < $scope.relatedExperiments.length; j++) {
- var currentExp = $scope.relatedExperiments[j], mutexs, targetSamplingPercentages;
- if (j === 0) {
- // Highest priority experiment, message will be different.
- currentExp.targetSamplingPercent = currentExp.samplingPercent.toFixed(4);
- }
- else {
- // For all others, we need to calculate the target sampling percentage by looking at the higher
- // priority experiments.
- mutexs = $scope.mutualExclusions[currentExp.label];
- targetSamplingPercentages = 0.0;
-
- for (var k = 0; k < mutexs.length; k++) {
- if (mutexs[k].priority < currentExp.priority) {
- // Get the value the user entered for this mutually exclusive experiment
- var relExp = $scope.relatedExperiments.filter(function(nextExp) {
- return nextExp.label === mutexs[k].label;
- });
- targetSamplingPercentages += parseFloat(relExp[0].targetSamplingPercent);
- }
- }
- var newTargetSamp = parseFloat(currentExp.samplingPercent) * (1 - targetSamplingPercentages);
- currentExp.targetSamplingPercent = parseFloat(newTargetSamp.toFixed(4));
- }
- }
- }
-
$scope.initialExperimentSelected = function() {
var i = 0;
$scope.relatedExperiments = [];
- $scope.meDoneNames = [];
$scope.mutualExclusions = {};
$scope.noCalc = false;
- //console.dir($scope.data.selectedExperiment);
+ // Find the selected experiment
var expSearch = $scope.experiments.filter(function(exp) {
return exp.label === $scope.data.selectedExperiment;
});
if (expSearch.length > 0) {
+ // Start the process of building the list of experiments related by mutual exclusions
$scope.relatedExperiments.push(JSON.parse(JSON.stringify(expSearch[0])));
$scope.setPriorityOnExperiment($scope.relatedExperiments[0]);
- console.log('Got priorities, get MEs for ' + expSearch[0].label);
+ // Prepare the structure used by TrafficManagementShared.getMutualExclusions() to keep track of which
+ // experiments we've gotten the mutual exclusions for.
+ $scope.pendingMEs = [{
+ label: expSearch[0].label,
+ processed: false
+ }];
$scope.getMutualExclusions($scope.relatedExperiments[0]);
}
@@ -207,7 +135,7 @@ angular.module('wasabi.controllers').
var cannotCalc = false;
for (var i = 0; i < $scope.relatedExperiments.length; i++) {
if ($scope.relatedExperiments[i].targetSamplingPercent.length === 0 ||
- $scope.relatedExperiments[i].targetSamplingPercent === 0.0) {
+ parseFloat($scope.relatedExperiments[i].targetSamplingPercent) === 0.0) {
UtilitiesFactory.displayPageError('Missing Target Sampling Percentage', 'Unable to calculate Experiment Sampling Percentages unless all Target Sampling Percentages have non-zero values.');
cannotCalc = true;
break;
@@ -280,6 +208,18 @@ angular.module('wasabi.controllers').
}
}
}
+ // Need to go through the list one more time to set up to display changes, if any. For some reason,
+ // the template doesn't seem able to do this.
+ for (var m = 0; m < $scope.relatedExperiments.length; m++) {
+ if (parseFloat($scope.relatedExperiments[m].originalSamplingPercent) !== parseFloat($scope.relatedExperiments[m].samplingPercent)) {
+ // The calculated sampling percent is new, so we want to display the old one.
+ $scope.relatedExperiments[m].oldSamplingPercent = $scope.multiply100($scope.relatedExperiments[m].originalSamplingPercent);
+ }
+ else {
+ $scope.relatedExperiments[m].oldSamplingPercent = '';
+ }
+ }
+ var x = 5;
};
$scope.save = function() {
diff --git a/modules/ui/app/plugins/traffic-management/template.html b/modules/ui/app/plugins/traffic-management/template.html
index a03cd06a2..046971d1c 100644
--- a/modules/ui/app/plugins/traffic-management/template.html
+++ b/modules/ui/app/plugins/traffic-management/template.html
@@ -24,7 +24,7 @@