_long_callback_interval_1 problems

Hello,

I am working on an app which contains steps that are computationally intensive and take time, thus using long_callbacks i am working with the DiskcacheLongCallbackManager method. Besides the initial callback ‘’ which can be detected via ctx = dash.callback_context and ctx.triggered[0]["prop_id"].split(".")[0] there is another callback fired: ‘_long_callback_interval_1’. This callback occurs randomly and screws up my computations, what is this callback for and how to prevent it / turn it off?

Thanks for the help

1 Like

Hi,

I believe this is pooling the status/results of the long callback task (which is some sort of internal dcc.Interval component…).

Could you elaborate in which sense your calculations are messed up by this callback?

Hello,

Sorry for being late, got the COVID-19 and was down for a few days. I think this triggers the calculations but it should not, only my button and my n_intervals from dcc.interval should trigger the callback. Is it also possible to not use long_callbacks but normal callbacks for computational expensive and time consuming tasks?

Hi @jlfsjunior,

I have the same problem with my code.

To replicate that problem:

  1. I picked code from the official documentation on page Long Callbacks | Dash for Python Documentation | Plotly, section Example 5: Progress Bar Chart Graph.
  2. I extended the code to run longer (total=1000)
  3. Set Network Throttling on Google my Chrome to “Slow 3G”

Using PyCharm I am able to set a breakpoint to the line following Why am I here?

Because my callback was triggered by _long_callback_interval_1.n_intervals component, calculations restarts. And this is exactly what I am trying to avoid.

Note - I tried to raise PreventUpdate - after detecting this unexpected callback - that didn’t help

Thanks in advance

Here is my code:

  1. requirements.txt
dash==2.2.0
dash_bootstrap_components==1.0.3
dash-core-components==2.0.0
dash-html-components==2.0.0
dash-table==5.0.0
diskcache==5.4.0
dash_tabulator==0.4.2
...
  1. I am using Python 3.9

  2. Output in the console

2022-03-10 21:14:20,758 INFO dash.py:2030 - Dash is running on http://127.0.0.1:8050/

 * Serving Flask app 'sample_long_callback' (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: on
Optimisation.Calculate. 1 - Button Click callback.
Optimisation.Calculate. 2 - Triggers: {'prop_id': 'button_id.n_clicks', 'value': 1}
Optimisation.Calculate. 3 - Button clicked 1 times
Optimisation.Calculate. 1 - Button Click callback.
Optimisation.Calculate. 2 - Triggers: {'prop_id': '_long_callback_interval_1.n_intervals', 'value': 130}
Optimisation.Calculate. 3 - Button clicked 1 times

  1. Code
import time
import dash
from dash import html, dcc
from dash.long_callback import DiskcacheLongCallbackManager
from dash.dependencies import Input, Output
import plotly.graph_objects as go


import diskcache

cache = diskcache.Cache("./cache")
long_callback_manager = DiskcacheLongCallbackManager(cache)


def make_progress_graph(progress, total):
    progress_graph = (
        go.Figure(data=[go.Bar(x=[progress])])
        .update_xaxes(range=[0, total])
        .update_yaxes(
            showticklabels=False,
        )
        .update_layout(height=100, margin=dict(t=20, b=40))
    )
    return progress_graph


app = dash.Dash(__name__, long_callback_manager=long_callback_manager)

app.layout = html.Div(
    [
        html.Div(
            [
                html.P(id="paragraph_id", children=["Button not clicked"]),
                dcc.Graph(id="progress_bar_graph", figure=make_progress_graph(0, 10)),
            ]
        ),
        html.Button(id="button_id", children="Run Job!"),
        html.Button(id="cancel_button_id", children="Cancel Running Job!"),
    ]
)


@app.long_callback(
    output=Output("paragraph_id", "children"),
    inputs=Input("button_id", "n_clicks"),
    running=[
        (Output("button_id", "disabled"), True, False),
        (Output("cancel_button_id", "disabled"), False, True),
        (
            Output("paragraph_id", "style"),
            {"visibility": "hidden"},
            {"visibility": "visible"},
        ),
        (
            Output("progress_bar_graph", "style"),
            {"visibility": "visible"},
            {"visibility": "hidden"},
        ),
    ],
    cancel=[Input("cancel_button_id", "n_clicks")],
    progress=Output("progress_bar_graph", "figure"),
    progress_default=make_progress_graph(0, 10),
    interval=1000,
    prevent_initial_call=True,
)
def callback(set_progress, n_clicks):

    print("Optimisation.Calculate. 1 - Button Click callback.")

    ctx = dash.callback_context
    print(f"Optimisation.Calculate. 2 - Triggers: {ctx.triggered[0]}")

    print(f"Optimisation.Calculate. 3 - Button clicked {n_clicks} times")

    if str(ctx.triggered[0]["prop_id"]).startswith("_long_callback_interval"):
        # Why am I here ???
        pass

    total = 1000
    for i in range(total):
        time.sleep(0.1)
        set_progress(make_progress_graph(i, 1000))

    return [f"Clicked {n_clicks} times"]


if __name__ == "__main__":
    app.run_server(debug=True)
1 Like

I have the same exact issue with _long_call_back_interval_1 triggering my long_callback. My callback is currently dependent on the trigger, so this is a big problem for me.

I am using Python3.8 and dash 2.3.0