You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by mi...@apache.org on 2022/09/14 20:41:53 UTC
[superset] 02/03: perf: Memoize the common_bootstrap_payload and include user param (#21018) (#21439)
This is an automated email from the ASF dual-hosted git repository.
michaelsmolina pushed a commit to branch 1.5
in repository https://gitbox.apache.org/repos/asf/superset.git
commit f3153760cd735ff478250686cc92b4eee4f7a374
Author: Bogdan <b....@gmail.com>
AuthorDate: Tue Sep 13 08:52:08 2022 -0700
perf: Memoize the common_bootstrap_payload and include user param (#21018) (#21439)
Co-authored-by: Bogdan Kyryliuk <bo...@dropbox.com>
---
superset/embedded/view.py | 4 ++--
superset/views/base.py | 26 ++++++++++++++++----------
superset/views/core.py | 10 +++++-----
superset/views/dashboard/views.py | 2 +-
tests/integration_tests/core_tests.py | 4 +++-
5 files changed, 27 insertions(+), 19 deletions(-)
diff --git a/superset/embedded/view.py b/superset/embedded/view.py
index 487850b728..b47ced6f9f 100644
--- a/superset/embedded/view.py
+++ b/superset/embedded/view.py
@@ -17,7 +17,7 @@
import json
from typing import Callable
-from flask import abort
+from flask import abort, g
from flask_appbuilder import expose
from flask_login import AnonymousUserMixin, LoginManager
@@ -65,7 +65,7 @@ class EmbeddedView(BaseSupersetView):
)
bootstrap_data = {
- "common": common_bootstrap_payload(),
+ "common": common_bootstrap_payload(g.user),
"embedded": {
"dashboard_id": embedded.dashboard_id,
},
diff --git a/superset/views/base.py b/superset/views/base.py
index ad89719ef8..f539ef202e 100644
--- a/superset/views/base.py
+++ b/superset/views/base.py
@@ -71,6 +71,7 @@ from superset.exceptions import (
SupersetException,
SupersetSecurityException,
)
+from superset.extensions import cache_manager
from superset.models.helpers import ImportExportMixin
from superset.models.reports import ReportRecipientType
from superset.superset_typing import FlaskResponse
@@ -288,7 +289,7 @@ class BaseSupersetView(BaseView):
def render_app_template(self) -> FlaskResponse:
payload = {
"user": bootstrap_user_data(g.user, include_perms=True),
- "common": common_bootstrap_payload(),
+ "common": common_bootstrap_payload(g.user),
}
return self.render_template(
"superset/spa.html",
@@ -299,7 +300,7 @@ class BaseSupersetView(BaseView):
)
-def menu_data() -> Dict[str, Any]:
+def menu_data(user: User) -> Dict[str, Any]:
menu = appbuilder.menu.get_data()
languages = {}
@@ -332,22 +333,27 @@ def menu_data() -> Dict[str, Any]:
"build_number": build_number,
"languages": languages,
"show_language_picker": len(languages.keys()) > 1,
- "user_is_anonymous": g.user.is_anonymous,
+ "user_is_anonymous": user.is_anonymous,
"user_info_url": None
if appbuilder.app.config["MENU_HIDE_USER_INFO"]
else appbuilder.get_url_for_userinfo,
"user_logout_url": appbuilder.get_url_for_logout,
"user_login_url": appbuilder.get_url_for_login,
"user_profile_url": None
- if g.user.is_anonymous or appbuilder.app.config["MENU_HIDE_USER_INFO"]
- else f"/superset/profile/{g.user.username}",
+ if user.is_anonymous or appbuilder.app.config["MENU_HIDE_USER_INFO"]
+ else f"/superset/profile/{user.username}",
"locale": session.get("locale", "en"),
},
}
-def common_bootstrap_payload() -> Dict[str, Any]:
- """Common data always sent to the client"""
+@cache_manager.cache.memoize(timeout=60)
+def common_bootstrap_payload(user: User) -> Dict[str, Any]:
+ """Common data always sent to the client
+
+ The function is memoized as the return value only changes based
+ on configuration and feature flag values.
+ """
messages = get_flashed_messages(with_categories=True)
locale = str(get_locale())
@@ -380,7 +386,7 @@ def common_bootstrap_payload() -> Dict[str, Any]:
"extra_sequential_color_schemes": conf["EXTRA_SEQUENTIAL_COLOR_SCHEMES"],
"extra_categorical_color_schemes": conf["EXTRA_CATEGORICAL_COLOR_SCHEMES"],
"theme_overrides": conf["THEME_OVERRIDES"],
- "menu_data": menu_data(),
+ "menu_data": menu_data(user),
}
bootstrap_data.update(conf["COMMON_BOOTSTRAP_OVERRIDES_FUNC"](bootstrap_data))
return bootstrap_data
@@ -491,7 +497,7 @@ def show_unexpected_exception(ex: Exception) -> FlaskResponse:
def get_common_bootstrap_data() -> Dict[str, Any]:
def serialize_bootstrap_data() -> str:
return json.dumps(
- {"common": common_bootstrap_payload()},
+ {"common": common_bootstrap_payload(g.user)},
default=utils.pessimistic_json_iso_dttm_ser,
)
@@ -509,7 +515,7 @@ class SupersetModelView(ModelView):
def render_app_template(self) -> FlaskResponse:
payload = {
"user": bootstrap_user_data(g.user, include_perms=True),
- "common": common_bootstrap_payload(),
+ "common": common_bootstrap_payload(g.user),
}
return self.render_template(
"superset/spa.html",
diff --git a/superset/views/core.py b/superset/views/core.py
index a4acaaa8bf..7a244fd278 100755
--- a/superset/views/core.py
+++ b/superset/views/core.py
@@ -933,7 +933,7 @@ class Superset(BaseSupersetView): # pylint: disable=too-many-public-methods
"force": force,
"user": bootstrap_user_data(g.user, include_perms=True),
"forced_height": request.args.get("height"),
- "common": common_bootstrap_payload(),
+ "common": common_bootstrap_payload(g.user),
}
if slc:
title = slc.slice_name
@@ -2035,7 +2035,7 @@ class Superset(BaseSupersetView): # pylint: disable=too-many-public-methods
bootstrap_data = {
"user": bootstrap_user_data(g.user, include_perms=True),
- "common": common_bootstrap_payload(),
+ "common": common_bootstrap_payload(g.user),
}
return self.render_template(
@@ -2853,7 +2853,7 @@ class Superset(BaseSupersetView): # pylint: disable=too-many-public-methods
payload = {
"user": bootstrap_user_data(g.user, include_perms=True),
- "common": common_bootstrap_payload(),
+ "common": common_bootstrap_payload(g.user),
}
return self.render_template(
@@ -2882,7 +2882,7 @@ class Superset(BaseSupersetView): # pylint: disable=too-many-public-methods
payload = {
"user": bootstrap_user_data(user, include_perms=True),
- "common": common_bootstrap_payload(),
+ "common": common_bootstrap_payload(g.user),
}
return self.render_template(
@@ -2946,7 +2946,7 @@ class Superset(BaseSupersetView): # pylint: disable=too-many-public-methods
"""SQL Editor"""
payload = {
"defaultDbId": config["SQLLAB_DEFAULT_DBID"],
- "common": common_bootstrap_payload(),
+ "common": common_bootstrap_payload(g.user),
**self._get_sqllab_tabs(g.user.get_id()),
}
diff --git a/superset/views/dashboard/views.py b/superset/views/dashboard/views.py
index 57d9b78092..65c7898341 100644
--- a/superset/views/dashboard/views.py
+++ b/superset/views/dashboard/views.py
@@ -163,7 +163,7 @@ class Dashboard(BaseSupersetView):
)
bootstrap_data = {
- "common": common_bootstrap_payload(),
+ "common": common_bootstrap_payload(g.user),
"embedded": {"dashboard_id": dashboard_id_or_slug},
}
diff --git a/tests/integration_tests/core_tests.py b/tests/integration_tests/core_tests.py
index f4788505c1..3cba31dafd 100644
--- a/tests/integration_tests/core_tests.py
+++ b/tests/integration_tests/core_tests.py
@@ -62,7 +62,7 @@ from superset.connectors.sqla.models import SqlaTable
from superset.db_engine_specs.base import BaseEngineSpec
from superset.db_engine_specs.mssql import MssqlEngineSpec
from superset.exceptions import SupersetException
-from superset.extensions import async_query_manager
+from superset.extensions import async_query_manager, cache_manager
from superset.models import core as models
from superset.models.annotations import Annotation, AnnotationLayer
from superset.models.dashboard import Dashboard
@@ -1446,6 +1446,8 @@ class TestCore(SupersetTestCase):
"""
Functions in feature flags don't break bootstrap data serialization.
"""
+ # feature flags are cached
+ cache_manager.cache.clear()
self.login()
encoded = json.dumps(