plotly / dash

Data Apps & Dashboards for Python. No JavaScript Required.
https://plotly.com/dash
MIT License
21.54k stars 2.08k forks source link

progress callable of a bg callback sometimes doesn't trigger #2828

Open jonnyrobbie opened 7 months ago

jonnyrobbie commented 7 months ago

python 3.10.13 dash 2.16.0

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:

Observed behaviour:

T4rk1n commented 7 months ago

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.

jonnyrobbie commented 7 months ago

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.