diff --git a/docs/faq.rst b/docs/faq.rst index 1777ca4681a..3fc8cefceb5 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -107,7 +107,8 @@ never be affected by any dashboard level filtering. "filter_immune_slice_fields": { "177": ["country_name", "__from", "__to"], "32": ["__from", "__to"] - } + }, + "timed_refresh_immune_slices": [324] } In the json blob above, slices 324, 65 and 92 won't be affected by any @@ -124,6 +125,24 @@ But what happens with filtering when dealing with slices coming from different tables or databases? If the column name is shared, the filter will 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: + +..code:: + + { + "filter_immune_slices": [], + "expanded_slices": {}, + "filter_immune_slice_fields": {}, + "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. + + Why does fabmanager or superset freezed/hung/not responding when started (my home directory is NFS mounted)? ----------------------------------------------------------------------------------------- superset creates and uses an sqlite database at ``~/.superset/superset.db``. Sqlite is known to `don't work well if used on NFS`__ due to broken file locking implementation on NFS. diff --git a/superset/assets/javascripts/dashboard/Dashboard.jsx b/superset/assets/javascripts/dashboard/Dashboard.jsx index 8b0a0e1c691..b6c97b68ecf 100644 --- a/superset/assets/javascripts/dashboard/Dashboard.jsx +++ b/superset/assets/javascripts/dashboard/Dashboard.jsx @@ -245,15 +245,18 @@ export function dashboardContainer(dashboard, datasources, userid) { 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; - setTimeout(() => { - slice.render(force); - }, - // Randomize to prevent all widgets refreshing at the same time - maxRandomDelay * Math.random()); + 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; }; diff --git a/superset/assets/spec/javascripts/dashboard/fixtures.jsx b/superset/assets/spec/javascripts/dashboard/fixtures.jsx index 7ac259e9416..7c822d78f98 100644 --- a/superset/assets/spec/javascripts/dashboard/fixtures.jsx +++ b/superset/assets/spec/javascripts/dashboard/fixtures.jsx @@ -43,6 +43,7 @@ export const dashboardData = { css: '', metadata: { filter_immune_slices: [], + timed_refresh_immune_slices: [], filter_immune_slice_fields: {}, expanded_slices: {}, }, diff --git a/superset/models/core.py b/superset/models/core.py index 5527f11d452..43cbeff5ae4 100644 --- a/superset/models/core.py +++ b/superset/models/core.py @@ -411,6 +411,7 @@ class Dashboard(Model, AuditMixinNullable, ImportMixin): slices = copy(dashboard_to_import.slices) old_to_new_slc_id_dict = {} new_filter_immune_slices = [] + new_timed_refresh_immune_slices = [] new_expanded_slices = {} i_params_dict = dashboard_to_import.params_dict for slc in slices: @@ -424,6 +425,10 @@ class Dashboard(Model, AuditMixinNullable, ImportMixin): if ('filter_immune_slices' in i_params_dict and old_slc_id_str in i_params_dict['filter_immune_slices']): new_filter_immune_slices.append(new_slc_id_str) + if ('timed_refresh_immune_slices' in i_params_dict and + old_slc_id_str in + i_params_dict['timed_refresh_immune_slices']): + new_timed_refresh_immune_slices.append(new_slc_id_str) if ('expanded_slices' in i_params_dict and old_slc_id_str in i_params_dict['expanded_slices']): new_expanded_slices[new_slc_id_str] = ( @@ -446,6 +451,9 @@ class Dashboard(Model, AuditMixinNullable, ImportMixin): if new_filter_immune_slices: dashboard_to_import.alter_params( filter_immune_slices=new_filter_immune_slices) + if new_timed_refresh_immune_slices: + dashboard_to_import.alter_params( + timed_refresh_immune_slices=new_timed_refresh_immune_slices) new_slices = session.query(Slice).filter( Slice.id.in_(old_to_new_slc_id_dict.values())).all() diff --git a/superset/views/core.py b/superset/views/core.py index e73ddc83804..a10e8848e2d 100755 --- a/superset/views/core.py +++ b/superset/views/core.py @@ -1343,6 +1343,8 @@ class Superset(BaseSupersetView): if 'filter_immune_slices' not in md: md['filter_immune_slices'] = [] + if 'timed_refresh_immune_slices' not in md: + md['timed_refresh_immune_slices'] = [] if 'filter_immune_slice_fields' not in md: md['filter_immune_slice_fields'] = {} md['expanded_slices'] = data['expanded_slices']