You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When using Pattern-Matching callbacks that use background callbacks, the current way things work. If the output is the "same", (same exact callback), it will cancel the first callback and start the new one.
Here is an example of three buttons designed to use pattern-matching to update the Divs above once the task is complete, however, the task never completes if you trigger another button push within the time of the first push:
import dash
from dash import dcc, html, Input, Output, ctx, MATCH, DiskcacheManager, no_update
import time
import diskcache
cache = diskcache.Cache("./cache")
background_callback_manager = DiskcacheManager(cache)
# Initialize the Dash app
app = dash.Dash(__name__, background_callback_manager=background_callback_manager)
# Define the layout of the app
app.layout = html.Div([
html.Div(id='progress-container', children=[
*[html.Div(id={'type': 'progress', 'index': i}, children=f'{i}') for i in range(3)],
*[html.Button(id={'type': 'button', 'index': i}, children=f'trigger-{i}') for i in range(3)]
]),
html.Div(id='test-out'),
html.Button(id='download_test', children='Download Test'),
dcc.Download(id='download_file')
])
# Pattern-matching callback to update progress
@app.callback(
Output({'type': 'progress', 'index': MATCH}, 'children'),
Input({'type': 'button', 'index': MATCH}, 'n_clicks'),
progress=[Output('test-out', 'children')],
background=True,
prevent_initial_call=True
)
def update_progress(set_progress, n):
if n:
count = 0
while count < 100:
count += 10
set_progress(f'{ctx.triggered_id.index} - {count}')
time.sleep(1)
# Read the existing data from the file
try:
with open('test.txt', 'r') as f:
data = f.readlines()
except:
data = []
# Append the new line to the data
data.append(f'{ctx.triggered_id.index} - {n}\n')
# Write the updated data back to the file
with open('test.txt', 'w') as f:
f.writelines(data)
return 'Task Complete!'
return no_update
@app.callback(
Output('download_file', 'data'),
Input('download_test', 'n_clicks'),
prevent_initial_call=True
)
def downfile(n):
if n:
with open('test.txt', 'r') as f:
data = f.read() # Read the entire file content
return dcc.send_bytes(data.encode(), filename='test.txt')
return no_update
# Run the app
if __name__ == '__main__':
app.run_server(debug=True)
It also doesnt just stop polling for the response from the server, it also completely drops the function call. This is dangerous, especially when dealing with processing in the background that need to complete.
Using the above example, I clicked all three buttons but only the third completed the task fully:
Here is the process that cancels the background running task, maybe we could allow for opting out of this check:
When using Pattern-Matching callbacks that use background callbacks, the current way things work. If the output is the "same", (same exact callback), it will cancel the first callback and start the new one.
Here is an example of three buttons designed to use pattern-matching to update the Divs above once the task is complete, however, the task never completes if you trigger another button push within the time of the first push:
It also doesnt just stop polling for the response from the server, it also completely drops the function call. This is dangerous, especially when dealing with processing in the background that need to complete.
Using the above example, I clicked all three buttons but only the third completed the task fully:
Here is the process that cancels the background running task, maybe we could allow for opting out of this check:
dash/dash/dash-renderer/src/actions/callbacks.ts
Lines 771 to 779 in 974d904
The text was updated successfully, but these errors were encountered: