-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Duplicate callback outputs with identical inputs (and potentially different states) fail #2486
Comments
This is the same callback two times, only the state differs and they will fire both at the same time. They should be combined for performance reason so there is only one request. Duplicate output now create the different callbacks based on the |
I'm fine with a different error message, the current one is just really unhelpful to solve the problem :) |
An interesting point from @tlauli, merging this in from #2546:
Being able to parallelize a callback this way is a really interesting use case. Unfortunately it's also one that potentially breaks many of the things we could do to disambiguate these callbacks in our internal tracking - which needs to be deterministic ESPECIALLY when we're talking about parallelizing since that implies multiple processes. Consider this pattern, which might look natural for this case: def create_trace_callback(trace_num):
@callback(Output("graph", "figure", allow_duplicate=True), Input("control", "value"))
def update_one_trace(value):
update = Patch().data[trace_num]
update.x, update.y = get_new_data(value, index=trace_num)
return update
for i in range(n_traces):
create_trace_callback(i) (edit: example updated, @T4rk1n points out my original syntax of creating the callback directly in a for loop would leave These would be all exactly the same function, just with a different value of the variable @callback(Output("graph", "figure", allow_duplicate=True), Input("control", "value"), key=i) |
I intended Initially it created a random uuid for the duplicate output but with multi workers and server restarts the uuid would not be the same and the callback would not be found. Thus the id for the outputs needs to be deterministic and the id is now created with a hash of the callback inputs. A workaround is to change the order of the inputs or add dummy inputs that are different across the callbacks. I think the states could be added to the created hash for that case can be a different callback that would be common as reported in this issue.
That could be a good solution it would take the key instead of the hash. |
Or include the key in the hash, in case you have other callbacks with the same outputs but different inputs.
Does it? In principle we should be able to get around that, detecting that another callback is in progress for the same output and waiting to rerender until that's done. |
Kinda, react do handle batch updates, it changed to be more automatic in react 18. |
Triggering render multiple times might be desirable. Back to the example with updating multiple traces of a |
Note that this happens if the callbacks have different outputs in addition to the common duplicated output as well. I guess I see the argument that they might as well be combined, but this can make the structure less organized IMO. One example would be when an interval is the input and multiple mostly independent things should happen regularly. The logic inside these callback could be such that the same input rarely will trigger writing to the same output at the same time. (and when they do the only expense is some compute) A better error message at the very least would be helpful. And if I understand correctly this does not trigger if the inputs is not exactly the same? The exact same issues can easily happen for such callbacks, so not sure I see why there should be an exception for the case where the input set is exactly the same. (adding the error message in plaintext for searchability: "Output 1 (...) is already in use. To resolve this, set (Also note that it's ok to have two such callbacks if one of them use |
Thank you @olejorgenb and @tlauli for your comments.
|
I have an input (a button in this case) and 2 callbacks. The first callback is fast and inserts the "loading..." indicator into the UI. The second, slow one clears the loading indicator and displays results. I believe this is a valid use-case for having 2 callbacks with exactly the same inputs and a duplicate output. At the moment this seems to be the simplest way to show a loading indicator for a callback that runs in the same process as the main app. |
@franekp We have Example:
|
Oh, this is nice, thanks! |
@T4rk1n is this one still relevant? |
Environment
Describe the bug
When 2 callbacks are created with a duplicate output (and
allow_duplicate=True
) and the sameInput
s (State
s can be different), Dash gives a Duplicate callback outputs error.Expected behavior
This should either:
Patch
so that things start displaying on the screen soonerI assume that this is due to a hashing that is done based on the
Input
s only, maybe it could include the decorated function name and theState
s in the hash as well?Current workaround: Adding a dummy
Input
in the callback saves the day.Screenshots
The text was updated successfully, but these errors were encountered: