Removed unneeded calls to get_rows. Added a queuing mechanism to protected against stacking up of calls to the server/ data updates.

Todo: refresh based on changes in the editor has scope problems
This commit is contained in:
Boaz Leskes 2014-01-09 15:49:30 +01:00
parent e1a3e47b02
commit 25a506a388
2 changed files with 107 additions and 31 deletions

View file

@ -3,22 +3,22 @@
<div class="section">
<div class="editor-option">
<label class="small">Mode</label>
<select class="input-small" ng-model="panel.mode" ng-options="f for f in ['nodes','indices']"></select>
<select ng-change="needs_refresh()" class="input-small" ng-model="panel.mode" ng-options="f for f in ['nodes','indices']"></select>
</div>
<div class="section" ng-show="panel.mode == 'nodes'">
<div class="editor-option">
<label class="small">Persistent id field <tip>choose a field that does not change on node restart</tip></label>
<input type="text" bs-typeahead="fields.list" ng-change="set_refresh(true)" class="input-large" ng-model="panel.persistent_field"/>
<input type="text" bs-typeahead="fields.list" ng-change="needs_refresh()" class="input-large" ng-model="panel.persistent_field"/>
</div>
<div class="editor-option">
<label class="small">Display field <tip>will be used as the name of each row</tip></label>
<input type="text" bs-typeahead="fields.list" class="input-large" ng-change="set_refresh(true)" ng-model="panel.display_field"/>
<input type="text" bs-typeahead="fields.list" class="input-large" ng-change="needs_refresh()" ng-model="panel.display_field"/>
</div>
</div>
<div class="section" ng-show="panel.mode == 'indices'">
<div class="editor-option">
<label class="small">Show hidden indices <tip>indices whose name starts with a dot (`.`) are considered hidden</tip></label>
<input type="checkbox" ng-model="panel.show_hidden" ng-change="set_refresh(true)"/>
<input type="checkbox" ng-model="panel.show_hidden" ng-change="needs_refresh()"/>
</div>
</div>
</div>
@ -69,7 +69,7 @@
<td ng-show="metricEditor.index != $index">
<i ng-show="metricEditor.index < 0" ng-click="set_refresh(true); metricEditor.index=$index;" class="pointer icon-edit"></i></td>
<i ng-show="metricEditor.index < 0" ng-click="needs_refresh(); metricEditor.index=$index;" class="pointer icon-edit"></i></td>
<td ng-show="metricEditor.index != $index">
<i ng-show="metricEditor.index < 0 && !$first" ng-click="_.move(panel.metrics,$index,$index-1)" class="pointer icon-arrow-up"></i>
</td>
@ -87,7 +87,7 @@
</tr>
</table>
<form class="form-inline">
<button class="btn btn-success" ng-click="set_refresh(true); addMetric()">Add Metric</button>
<button class="btn btn-success" ng-click="needs_refresh(); addMetric()">Add Metric</button>
</form>
</div>
</div>

View file

@ -13,6 +13,16 @@ define([
var module = angular.module('kibana.panels.marvel.stats_table', []);
app.useModule(module);
var log_debug;
if (false) {
log_debug = function (msg) {
console.log(msg);
};
} else {
log_debug = function () {
};
}
function y_format_metric_value(value, metric) {
// If this isn't a number, change nothing
if (_.isNaN(value) || !_.isFinite(value)) {
@ -190,7 +200,6 @@ define([
$scope.panel.metrics = _.map($scope.modeInfo[m].defaults.metrics, function (m) {
return metricDefaults(m);
});
_.throttle($scope.get_rows(), 500);
});
$scope.$watch('(rows|filter:panel.rowFilter).length', function (l) {
@ -198,17 +207,14 @@ define([
rowsVsRefresh(l);
});
$scope.$watch('dashboard.current.refresh',function() {
$scope.$watch('dashboard.current.refresh', function () {
var l = $filter('filter')($scope.rows, $scope.panel.rowFilter).length;
rowsVsRefresh(l);
});
$scope.$watch('panel.show_hidden', function () {
_.throttle($scope.get_rows(), 500);
});
var rowsVsRefresh = function(l) {
if(l > 5 && kbn.interval_to_seconds(dashboard.current.refresh || '1y') < 120) {
var rowsVsRefresh = function (l) {
if (l > 5 && kbn.interval_to_seconds(dashboard.current.refresh || '1y') < 120) {
$scope.panel.compact = true;
$scope.sparkLines = false;
$scope.viewSelect = false;
@ -230,17 +236,81 @@ define([
$scope.$on('refresh', function () {
$scope.get_rows();
});
$scope.get_rows();
};
$scope.get_mode_filter = function () {
return $scope.ejs.TermFilter("_type", $scope.panel.mode === "nodes" ? "node_stats" : "index_stats");
};
/*
marks the start of data retrieval. returns true if retrieval should continue
or false if not. May schedule future retrival if needed.
*/
$scope._register_data_start = function () {
var now = new Date();
if (!$scope._ongoing_data_retrieval) {
$scope._ongoing_data_retrieval = now; // mark start.
log_debug("marking data start for " + now);
return true;
}
if (now - $scope._ongoing_data_retrieval > 60000) {
console.log("previous data retrieval didn't finish within 1m. executing current request (previous: "
+ $scope._ongoing_data_retrieval + ")");
$scope._ongoing_data_retrieval = now; // mark start.
return true;
}
if (!$scope._pending_data_retrieval) {
// queue up, in case this is caused by something important, like an editor change.
log_debug("queueing data start for " + now);
$scope._pending_data_retrieval = now;
// safe guard time out to make sure it happens
setTimeout(function () {
if ($scope._pending_data_retrieval === now) {
// somehow this was not picked up... retry
console.log("Retrying call from " + now);
$scope._pending_data_retrieval = null;
$scope.get_rows();
}
}, 20000);
}
return false;
};
$scope._register_data_end = function () {
log_debug("end of data retrieval " + $scope._ongoing_data_retrieval);
if ($scope._pending_data_retrieval) {
var pending = $scope._pending_data_retrieval;
setTimeout(function () {
$scope._ongoing_data_retrieval = null;
if (pending !== $scope._pending_data_retrieval) {
log_debug("firing pending retrieval canceled as it was picked up: " + pending);
return;
}
log_debug("firing pending retrieval " + $scope._pending_data_retrieval);
$scope._pending_data_retrieval = null;
$scope.get_rows();
}, 5000); // leave 5 second of some breathing air
} else {
$scope._ongoing_data_retrieval = null;
}
};
$scope.get_rows = function () {
if (dashboard.indices.length === 0) {
return;
}
if (!$scope._register_data_start()) {
return;
}
var
request,
filter,
@ -272,6 +342,7 @@ define([
results = request.doSearch();
results.then(function (r) {
var newPersistentIds = _.pluck(r.facets.terms.terms, 'term'),
mrequest;
@ -331,8 +402,8 @@ define([
});
});
$scope.get_data(newRows);
});
});
}, $scope._register_data_end);
}, $scope._register_data_end);
};
@ -348,6 +419,7 @@ define([
$scope.data = {};
$scope.panelMeta.loading = false;
$scope.calculateWarnings();
$scope._register_data_end();
return;
}
@ -385,11 +457,14 @@ define([
// Populate scope when we have results
results.then(function (results) {
$scope.rows = newRows;
$scope.data = normalizeFacetResults(results.facets, newRows, $scope.panel.metrics);
$scope.panelMeta.loading = false;
$scope.calculateWarnings();
});
$scope.rows = newRows;
$scope.data = normalizeFacetResults(results.facets, newRows, $scope.panel.metrics);
$scope.panelMeta.loading = false;
$scope.calculateWarnings();
$scope._register_data_end();
},
$scope._register_data_end
);
};
var normalizeFacetResults = function (facets, rows, metrics) {
@ -650,27 +725,28 @@ define([
});
};
$scope.needs_refresh = function (value) {
if (_.isUndefined(value)) {
value = true;
}
$scope.needs_refresh = value;
};
$scope.close_edit = function () {
$scope.metricEditor = {
index: -1
};
if ($scope.needs_refresh) {
$scope.get_rows();
}
$scope.needs_refresh = false;
$scope.$emit('render');
};
$scope.deleteMetric = function (index) {
$scope.panel.metrics = _.without($scope.panel.metrics, $scope.panel.metrics[index]);
};
$scope.set_refresh = function (state) {
$scope.refresh = state;
};
$scope.close_edit = function () {
if ($scope.refresh) {
$scope.get_rows();
}
$scope.refresh = false;
$scope.$emit('render');
};
});