dash
dash copied to clipboard
progress callable of a bg callback sometimes doesn't trigger
python 3.10.13 dash 2.16.0
-
if frontend related, tell us your Browser, Version and OS
- OS: macos 14.4
- Browser firefox
- Version 124.0.2
Describe the bug
A function callable of a callback with a progress param doesn't seem to get hooked immediately. And calls to this callable seem to be ignored sometimes - especially fraction of a seconds after the callback itself has been triggered.
Expected behavior
MVE:
from dash import html, Input, Output, Dash, callback, DiskcacheManager
import diskcache
import time
cache = diskcache.Cache("./cache")
background_callback_manager = DiskcacheManager(cache)
app = Dash(__name__, background_callback_manager=background_callback_manager)
app.layout = html.Div(
[html.Div(id="result"), html.Div(id="progress"), html.Button("Run", id="run")]
)
@callback(
[Output("result", "children")],
[Input("run", "n_clicks")],
prevent_initial_call=True,
background=True,
running=[(Output("run", "disabled"), True, False)],
progress=[Output("progress", "children")],
)
def run(set_progress, n):
# time.sleep(1)
set_progress("running")
time.sleep(1)
set_progress("still running")
time.sleep(1) # long running function
set_progress("finished")
return (f"Run clicked {n} times",)
if __name__ == "__main__":
app.run(debug=True)
Run this app and click the button.
Expected behaviour:
- it shows "running immediately after pressing the button. Then after a second, "still sunning" is shown and after yet another second "finished" is displayed and stays on the screen.
Observed behaviour:
- after clicking a button, nothing changes for a second, and then it shows "still running". The first call to set_progress at the beginning of the callback seems to be ignored.
- if you uncomment the time.sleep call, then the first call to set_progress seems to go through.
it shows "running immediately after pressing the button. Then after a second, "still sunning" is shown and after yet another second "finished" is displayed and stays on the screen.
If you have a sleep for 1 second, before setting "running" it is never going to appear right with the default settings.
The background callbacks operates a chains of requests, it wait for interval
argument which by default is 1000 ms. You can set the interval
to a lower amount to ensure faster retrieval of progress values.
The documentation is extremely unclear of the inner workings. The https://dash.plotly.com/background-callbacks sections does not mention the behaviour you mentioned at all and does not mention any limitations for the bg callback progress callable. API reference just says "interval - Time to wait between the long callback update requests.", which explains very little.