Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix cache key issue #3190

Open
wants to merge 3 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ This project adheres to [Semantic Versioning](https://semver.org/).

- [#3080](https://github.com/plotly/dash/pull/3080) Fix docstring generation for components using single-line or nonstandard-indent leading comments
- [#3103](https://github.com/plotly/dash/pull/3103) Fix Graph component becomes unresponsive if an invalid figure is passed
- [#3190](https://github.com/plotly/dash/pull/3190) Fix issue with cache key generation by adding option to include triggered inputs. Fixes [#3189](https://github.com/plotly/dash/issues/3189)

## [2.18.2] - 2024-11-04

Expand Down
11 changes: 11 additions & 0 deletions dash/_callback.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ def callback(
cancel=None,
manager=None,
cache_args_to_ignore=None,
cache_ignore_triggered=True,
on_error: Optional[Callable[[Exception], Any]] = None,
**_kwargs,
):
Expand Down Expand Up @@ -139,6 +140,9 @@ def callback(
with keyword arguments (Input/State provided in a dict),
this should be a list of argument names as strings. Otherwise,
this should be a list of argument indices as integers.
:param cache_ignore_triggered:
Whether to ignore which inputs triggered the callback when creating
the cache.
:param interval:
Time to wait between the long callback update requests.
:param on_error:
Expand Down Expand Up @@ -185,6 +189,8 @@ def callback(
if cache_args_to_ignore:
long_spec["cache_args_to_ignore"] = cache_args_to_ignore

long_spec["cache_ignore_triggered"] = cache_ignore_triggered

return register_callback(
callback_list,
callback_map,
Expand Down Expand Up @@ -393,11 +399,16 @@ def add_context(*args, **kwargs):
job_id = flask.request.args.get("job")
old_job = flask.request.args.getlist("oldJob")

cache_ignore_triggered = long.get("cache_ignore_triggered", True)

current_key = callback_manager.build_cache_key(
func,
# Inputs provided as dict is kwargs.
func_args if func_args else func_kwargs,
long.get("cache_args_to_ignore", []),
None
if cache_ignore_triggered
else callback_ctx.get("triggered_inputs", []),
)

if old_job:
Expand Down
4 changes: 2 additions & 2 deletions dash/long_callback/managers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def get_result(self, key, job):
def get_updated_props(self, key):
raise NotImplementedError

def build_cache_key(self, fn, args, cache_args_to_ignore):
def build_cache_key(self, fn, args, cache_args_to_ignore, triggered):
fn_source = inspect.getsource(fn)

if not isinstance(cache_args_to_ignore, (list, tuple)):
Expand All @@ -68,7 +68,7 @@ def build_cache_key(self, fn, args, cache_args_to_ignore):
arg for i, arg in enumerate(args) if i not in cache_args_to_ignore
]

hash_dict = dict(args=args, fn_source=fn_source)
hash_dict = dict(args=args, fn_source=fn_source, triggered=triggered)

if self.cache_by is not None:
# Caching enabled
Expand Down
2 changes: 1 addition & 1 deletion dash/long_callback/managers/celery_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def __init__(self, celery_app, cache_by=None, expire=None):
:param cache_by:
A list of zero-argument functions. When provided, caching is enabled and
the return values of these functions are combined with the callback
function's input arguments and source code to generate cache keys.
function's input arguments, triggered inputs and source code to generate cache keys.
:param expire:
If provided, a cache entry will be removed when it has not been accessed
for ``expire`` seconds. If not provided, the lifetime of cache entries
Expand Down
2 changes: 1 addition & 1 deletion dash/long_callback/managers/diskcache_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def __init__(self, cache=None, cache_by=None, expire=None):
:param cache_by:
A list of zero-argument functions. When provided, caching is enabled and
the return values of these functions are combined with the callback
function's input arguments and source code to generate cache keys.
function's input arguments, triggered inputs and source code to generate cache keys.
:param expire:
If provided, a cache entry will be removed when it has not been accessed
for ``expire`` seconds. If not provided, the lifetime of cache entries
Expand Down