Skip to content

Commit

Permalink
feat: add ability to disable cache
Browse files Browse the repository at this point in the history
  • Loading branch information
villebro committed Mar 21, 2023
1 parent b0d83e8 commit 8a43a2f
Show file tree
Hide file tree
Showing 9 changed files with 38 additions and 16 deletions.
3 changes: 3 additions & 0 deletions docs/docs/installation/cache.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ The cache timeout for charts may be overridden by the settings for an individual
database. Each of these configurations will be checked in order before falling back to the default
value defined in `DATA_CACHE_CONFIG.

Note, that by setting the cache timeout to `-1`, caching for charting data can be disabled, either
per chart, dataset or database, or by default if set in `DATA_CACHE_CONFIG`.

### SQL Lab Query Results

Caching for SQL Lab query results is used when async queries are enabled and is configured using
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -938,7 +938,7 @@ class DatasourceEditor extends React.PureComponent {
fieldKey="cache_timeout"
label={t('Cache timeout')}
description={t(
'The duration of time in seconds before the cache is invalidated',
'The duration of time in seconds before the cache is invalidated. Set to -1 to bypass the cache.',
)}
control={<TextControl controlId="cache_timeout" />}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ const DatasourceModal: FunctionComponent<DatasourceModalProps> = ({
postPayload: {
data: {
...currentDatasource,
cache_timeout:
currentDatasource.cache_timeout === ''
? null
: currentDatasource.cache_timeout,
schema,
metrics: currentDatasource?.metrics?.map(
(metric: Record<string, unknown>) => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ function PropertiesModal({
</StyledFormItem>
<StyledHelpBlock className="help-block">
{t(
"Duration (in seconds) of the caching timeout for this chart. Note this defaults to the dataset's timeout if undefined.",
"Duration (in seconds) of the caching timeout for this chart. Set to -1 to bypass the cache. Note this defaults to the dataset's timeout if undefined.",
)}
</StyledHelpBlock>
</FormItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ const ExtraOptions = ({
<div className="helper">
{t(
'Duration (in seconds) of the caching timeout for charts of this database.' +
' A timeout of 0 indicates that the cache never expires.' +
' A timeout of 0 indicates that the cache never expires, and -1 bypasses the cache.' +
' Note this defaults to the global timeout if undefined.',
)}
</div>
Expand Down
5 changes: 4 additions & 1 deletion superset/common/query_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,10 @@ def get_df_payload(
query_obj: QueryObject,
force_cached: Optional[bool] = False,
) -> Dict[str, Any]:
return self._processor.get_df_payload(query_obj, force_cached)
return self._processor.get_df_payload(
query_obj=query_obj,
force_cached=force_cached,
)

def get_query_result(self, query_object: QueryObject) -> QueryResult:
return self._processor.get_query_result(query_object)
Expand Down
12 changes: 7 additions & 5 deletions superset/common/query_context_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,13 @@ def get_df_payload(
) -> Dict[str, Any]:
"""Handles caching around the df payload retrieval"""
cache_key = self.query_cache_key(query_obj)
timeout = self.get_cache_timeout()
force_query = self._query_context.force or timeout == -1
cache = QueryCacheManager.get(
cache_key,
CacheRegion.DATA,
self._query_context.force,
force_cached,
key=cache_key,
region=CacheRegion.DATA,
force_query=force_query,
force_cached=force_cached,
)

if query_obj and cache_key and not cache.is_loaded:
Expand Down Expand Up @@ -139,7 +141,7 @@ def get_df_payload(
key=cache_key,
query_result=query_result,
annotation_data=annotation_data,
force_query=self._query_context.force,
force_query=force_query,
timeout=self.get_cache_timeout(),
datasource_uid=self._qc_datasource.uid,
region=CacheRegion.DATA,
Expand Down
16 changes: 9 additions & 7 deletions superset/viz.py
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,9 @@ def get_df_payload( # pylint: disable=too-many-statements
is_loaded = False
stacktrace = None
df = None
if cache_key and cache_manager.data_cache and not self.force:
cache_timeout = self.cache_timeout
force = self.force or cache_timeout == -1
if cache_key and cache_manager.data_cache and not force:
cache_value = cache_manager.data_cache.get(cache_key)
if cache_value:
stats_logger.incr("loading_from_cache")
Expand Down Expand Up @@ -609,16 +611,16 @@ def get_df_payload( # pylint: disable=too-many-statements

if is_loaded and cache_key and self.status != QueryStatus.FAILED:
set_and_log_cache(
cache_manager.data_cache,
cache_key,
{"df": df, "query": self.query},
self.cache_timeout,
self.datasource.uid,
cache_instance=cache_manager.data_cache,
cache_key=cache_key,
cache_value={"df": df, "query": self.query},
cache_timeout=cache_timeout,
datasource_uid=self.datasource.uid,
)
return {
"cache_key": cache_key,
"cached_dttm": cache_value["dttm"] if cache_value is not None else None,
"cache_timeout": self.cache_timeout,
"cache_timeout": cache_timeout,
"df": df,
"errors": self.errors,
"form_data": self.form_data,
Expand Down
8 changes: 8 additions & 0 deletions tests/integration_tests/charts/data/api_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -1132,6 +1132,14 @@ def test_custom_cache_timeout(test_client, login_as_admin, physical_query_contex
assert rv.json["result"][0]["cache_timeout"] == 5678


def test_force_cache_timeout(test_client, login_as_admin, physical_query_context):
physical_query_context["custom_cache_timeout"] = -1
test_client.post(CHART_DATA_URI, json=physical_query_context)
rv = test_client.post(CHART_DATA_URI, json=physical_query_context)
assert rv.json["result"][0]["cached_dttm"] is None
assert rv.json["result"][0]["is_cached"] is None


@mock.patch(
"superset.common.query_context_processor.config",
{
Expand Down

0 comments on commit 8a43a2f

Please sign in to comment.