Skip to content

cannot set value of output to previous value after background callback resets one of its own outputs #3189

Closed
@MartinSA04

Description

@MartinSA04
dash                 2.18.2
dash-core-components 2.0.0
dash-html-components 2.0.0
dash-table           5.0.0

Describe the bug
When a background callback resets one of its own outputs, you cannot set the value of that output back to the previous value, because the basis for the cache key would be the same, and the cached result would be returned. This is an edge case, but it happens frequently enough to warrant a change.

Expected behavior

A callback invoked with the same input values, but different triggered inputs should not retrieve the cached result.

minimal example:
Select "World", and wait for the callback to finish. Press "clear page", and wait for the callback to finish. If you now try to select "World", you cannot do so.

import dash
from dash import html, dcc, Input, Output, no_update
import diskcache
from dash import DiskcacheManager
from uuid import uuid4
import time

launch_uid = uuid4()

cache = diskcache.Cache("./cache")
background_callback_manager = DiskcacheManager(
    cache, cache_by=[lambda: launch_uid], expire=60
)

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

app.layout = html.Div(
    [
        dcc.RadioItems(["Hello", "World"], id="input", value="Hello"),
        html.Div(id="output", children="Hello is selected"),
        html.Button("clear page", id="button"),
    ]
)

@app.callback(
    Output("output", "children"),
    Output("input", "value"),
    Input("input", "value"),
    Input("button", "n_clicks"),
    prevent_initial_call=True,
    background=True
)
def update_output(value, n_clicks):
    triggered_id = dash.callback_context.triggered_id
    print(triggered_id)
    time.sleep(5)
    match triggered_id:
        case "input":
            return value + " is selected", no_update
        case "button":
            return "Hello is selected", "Hello"
        case _:
            return no_update, no_update

if __name__ == "__main__":
    app.run_server()

Metadata

Metadata

Assignees

Labels

P2considered for next cyclebugsomething brokendash-3.0Going in dash-3.0 release.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions