You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by ma...@apache.org on 2017/10/04 17:23:19 UTC
[incubator-superset] branch master updated: [Bugfix/Feature] Fixed
slice render staggering on dashboard first load (#3478)
This is an automated email from the ASF dual-hosted git repository.
maximebeauchemin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git
The following commit(s) were added to refs/heads/master by this push:
new e95132d [Bugfix/Feature] Fixed slice render staggering on dashboard first load (#3478)
e95132d is described below
commit e95132ddc3521adf23e5721a7e1bdb93df53c351
Author: Jeff Niu <je...@gmail.com>
AuthorDate: Wed Oct 4 10:23:17 2017 -0700
[Bugfix/Feature] Fixed slice render staggering on dashboard first load (#3478)
* Feature: disable dashboard refresh staggering
* Removed refresh staggering everywhere except during periodic render
---
docs/faq.rst | 25 +++++++++--
.../assets/javascripts/dashboard/Dashboard.jsx | 48 +++++++++++-----------
.../javascripts/dashboard/components/Controls.jsx | 5 +--
superset/assets/javascripts/modules/superset.js | 4 ++
4 files changed, 51 insertions(+), 31 deletions(-)
diff --git a/docs/faq.rst b/docs/faq.rst
index 1c70fc8..cee767a 100644
--- a/docs/faq.rst
+++ b/docs/faq.rst
@@ -128,8 +128,11 @@ be applied, it's as simple as that.
How to limit the timed refresh on a dashboard?
----------------------------------------------
-By default, the dashboard timed refresh feature allows you to automatically requery every slice on a dashboard according to a set schedule. Sometimes, however, you won't want all of the slices to be refreshed - especially if some data is slow moving, or run heavy queries.
-To exclude specific slices from the timed refresh process, add the ``timed_refresh_immune_slices`` key to the dashboard ``JSON Metadata`` field:
+By default, the dashboard timed refresh feature allows you to automatically re-query every slice
+on a dashboard according to a set schedule. Sometimes, however, you won't want all of the slices
+to be refreshed - especially if some data is slow moving, or run heavy queries. To exclude specific
+slices from the timed refresh process, add the ``timed_refresh_immune_slices`` key to the dashboard
+``JSON Metadata`` field:
..code::
@@ -140,8 +143,22 @@ To exclude specific slices from the timed refresh process, add the ``timed_refre
"timed_refresh_immune_slices": [324]
}
-In the example above, if a timed refresh is set for the dashboard, then every slice except 324 will be automatically requeried on schedule.
+In the example above, if a timed refresh is set for the dashboard, then every slice except 324 will
+be automatically re-queried on schedule.
+Slice refresh will also be staggered over the specified period. You can turn off this staggering
+by setting the ``stagger_refresh`` to ``false`` and modify the stagger period by setting
+``stagger_time`` to a value in milliseconds in the ``JSON Metadata`` field:
+
+..code::
+
+ {
+ "stagger_refresh": false,
+ "stagger_time": 2500
+ }
+
+Here, the entire dashboard will refresh at once if periodic refresh is on. The stagger time of
+2.5 seconds is ignored.
Why does fabmanager or superset freezed/hung/not responding when started (my home directory is NFS mounted)?
-----------------------------------------------------------------------------------------
@@ -188,7 +205,7 @@ Please note that pretty much any databases that have a SqlAlchemy integration sh
How can i configure OAuth authentication and authorization?
-----------------------------------------------------------
-You can take a look at this Flask-AppBuilder `configuration example
+You can take a look at this Flask-AppBuilder `configuration example
<https://github.com/dpgaspar/Flask-AppBuilder/blob/master/examples/oauth/config.py>`_.
How can I set a default filter on my dashboard?
diff --git a/superset/assets/javascripts/dashboard/Dashboard.jsx b/superset/assets/javascripts/dashboard/Dashboard.jsx
index eb471da..5d150a2 100644
--- a/superset/assets/javascripts/dashboard/Dashboard.jsx
+++ b/superset/assets/javascripts/dashboard/Dashboard.jsx
@@ -126,7 +126,8 @@ export function dashboardContainer(dashboard, datasources, userid) {
}
});
this.loadPreSelectFilters();
- this.startPeriodicRender(0);
+ this.renderSlices(this.sliceObjects);
+ this.firstLoad = false;
this.bindResizeToWindowResize();
},
onChange() {
@@ -254,25 +255,31 @@ export function dashboardContainer(dashboard, datasources, userid) {
this.refreshTimer = null;
}
},
+ renderSlices(slices, force = false, interval = 0) {
+ if (!interval) {
+ slices.forEach(slice => slice.render(force));
+ return;
+ }
+ const meta = this.metadata;
+ const refreshTime = Math.max(interval, meta.stagger_time || 5000); // default 5 seconds
+ if (typeof meta.stagger_refresh !== 'boolean') {
+ meta.stagger_refresh = meta.stagger_refresh === undefined ?
+ true : meta.stagger_refresh === 'true';
+ }
+ const delay = meta.stagger_refresh ? refreshTime / (slices.length - 1) : 0;
+ slices.forEach((slice, i) => {
+ setTimeout(() => slice.render(force), delay * i);
+ });
+ },
startPeriodicRender(interval) {
this.stopPeriodicRender();
const dash = this;
const immune = this.metadata.timed_refresh_immune_slices || [];
- const maxRandomDelay = Math.max(interval * 0.2, 5000);
const refreshAll = () => {
- dash.sliceObjects.forEach((slice) => {
- const force = !dash.firstLoad;
- if (immune.indexOf(slice.data.slice_id) === -1) {
- setTimeout(() => {
- slice.render(force);
- },
- // Randomize to prevent all widgets refreshing at the same time
- maxRandomDelay * Math.random());
- }
- });
- dash.firstLoad = false;
+ const slices = dash.sliceObjects
+ .filter(slice => immune.indexOf(slice.data.slice_id) === -1);
+ dash.renderSlices(slices, true, interval * 0.2);
};
-
const fetchAndRender = function () {
refreshAll();
if (interval > 0) {
@@ -285,16 +292,9 @@ export function dashboardContainer(dashboard, datasources, userid) {
},
refreshExcept(sliceId) {
const immune = this.metadata.filter_immune_slices || [];
- this.sliceObjects.forEach((slice) => {
- if (slice.data.slice_id !== sliceId && immune.indexOf(slice.data.slice_id) === -1) {
- slice.render();
- const sliceSeletor = $(`#${slice.data.slice_id}-cell`);
- sliceSeletor.addClass('slice-cell-highlight');
- setTimeout(function () {
- sliceSeletor.removeClass('slice-cell-highlight');
- }, 1200);
- }
- });
+ const slices = this.sliceObjects.filter(slice =>
+ slice.data.slice_id !== sliceId && immune.indexOf(slice.data.slice_id) === -1);
+ this.renderSlices(slices);
},
clearFilters(sliceId) {
delete this.filters[sliceId];
diff --git a/superset/assets/javascripts/dashboard/components/Controls.jsx b/superset/assets/javascripts/dashboard/components/Controls.jsx
index e18c270..5d24055 100644
--- a/superset/assets/javascripts/dashboard/components/Controls.jsx
+++ b/superset/assets/javascripts/dashboard/components/Controls.jsx
@@ -35,9 +35,8 @@ class Controls extends React.PureComponent {
});
}
refresh() {
- this.props.dashboard.sliceObjects.forEach((slice) => {
- slice.render(true);
- });
+ // Force refresh all slices
+ this.props.dashboard.renderSlices(this.props.dashboard.sliceObjects, true);
}
changeCss(css) {
this.setState({ css });
diff --git a/superset/assets/javascripts/modules/superset.js b/superset/assets/javascripts/modules/superset.js
index a1723eb..6570aba 100644
--- a/superset/assets/javascripts/modules/superset.js
+++ b/superset/assets/javascripts/modules/superset.js
@@ -65,6 +65,7 @@ const px = function (state) {
const container = $(selector);
const sliceId = data.slice_id;
const formData = applyDefaultFormData(data.form_data);
+ const sliceCell = $(`#${data.slice_id}-cell`);
slice = {
data,
formData,
@@ -114,6 +115,7 @@ const px = function (state) {
token.find('img.loading').hide();
container.fadeTo(0.5, 1);
+ sliceCell.removeClass('slice-cell-highlight');
container.show();
$('.query-and-save button').removeAttr('disabled');
@@ -139,6 +141,7 @@ const px = function (state) {
let errorMsg = msg;
token.find('img.loading').hide();
container.fadeTo(0.5, 1);
+ sliceCell.removeClass('slice-cell-highlight');
let errHtml = '';
let o;
try {
@@ -211,6 +214,7 @@ const px = function (state) {
controls.find('a.exportCSV').attr('href', getExploreUrl(formDataExtra, 'csv'));
token.find('img.loading').show();
container.fadeTo(0.5, 0.25);
+ sliceCell.addClass('slice-cell-highlight');
container.css('height', this.height());
$.ajax({
url: this.jsonEndpoint(formDataExtra),
--
To stop receiving notification emails like this one, please contact
['"commits@superset.apache.org" <co...@superset.apache.org>'].