feat: add ability to disable cache (#23439)

This commit is contained in:
Ville Brofeldt 2023-03-31 11:41:57 +03:00 committed by GitHub
parent f6b5b658e5
commit 500d90058f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 38 additions and 16 deletions

View File

@ -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

View File

@ -944,7 +944,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" />}
/>

View File

@ -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>) => ({

View File

@ -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>

View File

@ -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>

View File

@ -118,7 +118,10 @@ class QueryContext:
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)

View File

@ -106,11 +106,13 @@ class QueryContextProcessor:
) -> 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:
@ -139,7 +141,7 @@ class QueryContextProcessor:
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,

View File

@ -526,7 +526,9 @@ class BaseViz: # pylint: disable=too-many-public-methods
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")
@ -609,16 +611,16 @@ class BaseViz: # pylint: disable=too-many-public-methods
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,

View File

@ -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",
{