Skip to content

Commit d13a917

Browse files
committed
Create a single cancel callback for each unique input.
1 parent ce0aabe commit d13a917

File tree

2 files changed

+25
-19
lines changed

2 files changed

+25
-19
lines changed

dash/_callback.py

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
from .exceptions import (
1313
PreventUpdate,
1414
WildcardInLongCallback,
15-
DuplicateCallback,
1615
MissingLongCallbackManagerError,
1716
LongCallbackError,
1817
)
@@ -171,25 +170,8 @@ def callback(
171170
cancel_inputs = coerce_to_list(cancel)
172171
validate_long_inputs(cancel_inputs)
173172

174-
cancels_output = [Output(c.component_id, "id") for c in cancel_inputs]
175-
176-
try:
177-
178-
@callback(cancels_output, cancel_inputs, prevent_initial_call=True)
179-
def cancel_call(*_):
180-
job_ids = flask.request.args.getlist("cancelJob")
181-
executor = (
182-
manager or context_value.get().background_callback_manager
183-
)
184-
if job_ids:
185-
for job_id in job_ids:
186-
executor.terminate_job(job_id)
187-
return NoUpdate()
188-
189-
except DuplicateCallback:
190-
pass # Already a callback to cancel, will get the proper jobs from the store.
191-
192173
long_spec["cancel"] = [c.to_dict() for c in cancel_inputs]
174+
long_spec["cancel_inputs"] = cancel_inputs
193175

194176
if cache_args_to_ignore:
195177
long_spec["cache_args_to_ignore"] = cache_args_to_ignore

dash/dash.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1316,6 +1316,30 @@ def _setup_server(self):
13161316

13171317
_validate.validate_long_callbacks(self.callback_map)
13181318

1319+
cancels = set()
1320+
1321+
for callback in self.callback_map.values():
1322+
cancel = callback.get("long", {}).pop("cancel_inputs")
1323+
if cancel:
1324+
cancels.update(cancel)
1325+
1326+
if cancels:
1327+
for cancel_input in cancels:
1328+
1329+
# pylint: disable=cell-var-from-loop
1330+
@self.callback(
1331+
Output(cancel_input.component_id, "id"),
1332+
cancel_input,
1333+
prevent_initial_call=True,
1334+
)
1335+
def cancel_call(*_):
1336+
job_ids = flask.request.args.getlist("cancelJob")
1337+
executor = _callback.context_value.get().background_callback_manager
1338+
if job_ids:
1339+
for job_id in job_ids:
1340+
executor.terminate_job(job_id)
1341+
return no_update
1342+
13191343
def _add_assets_resource(self, url_path, file_path):
13201344
res = {"asset_path": url_path, "filepath": file_path}
13211345
if self.config.assets_external_path:

0 commit comments

Comments
 (0)