Submit callback to executor for thread pool execution. This function creates a callback execution context and runs it in a separate thread. Both sync and async callbacks are supported. Args: executor: ThreadPoolExecutor to submit the task to dash_app: The Dash applicati
(
executor: ThreadPoolExecutor,
dash_app: "dash.Dash",
payload: CallbackExecutionBody,
ws_callback: DashWebsocketCallback,
response_adapter: "ResponseAdapter",
)
| 392 | |
| 393 | |
| 394 | def run_callback_in_executor( |
| 395 | executor: ThreadPoolExecutor, |
| 396 | dash_app: "dash.Dash", |
| 397 | payload: CallbackExecutionBody, |
| 398 | ws_callback: DashWebsocketCallback, |
| 399 | response_adapter: "ResponseAdapter", |
| 400 | ) -> concurrent.futures.Future: |
| 401 | """Submit callback to executor for thread pool execution. |
| 402 | |
| 403 | This function creates a callback execution context and runs it |
| 404 | in a separate thread. Both sync and async callbacks are supported. |
| 405 | |
| 406 | Args: |
| 407 | executor: ThreadPoolExecutor to submit the task to |
| 408 | dash_app: The Dash application instance |
| 409 | payload: The callback payload from WebSocket message |
| 410 | ws_callback: WebSocket callback instance for set_prop/get_prop |
| 411 | response_adapter: Response adapter for the backend |
| 412 | |
| 413 | Returns: |
| 414 | Future representing the pending callback execution |
| 415 | """ |
| 416 | |
| 417 | def execute() -> dict: |
| 418 | try: |
| 419 | cb_ctx = create_ws_context(payload, response_adapter, ws_callback) |
| 420 | # pylint: disable=protected-access |
| 421 | func = dash_app._prepare_callback(cb_ctx, payload) |
| 422 | args = dash_app._inputs_to_vals( # pylint: disable=protected-access |
| 423 | cb_ctx.inputs_list + cb_ctx.states_list |
| 424 | ) |
| 425 | |
| 426 | ctx = copy_context() |
| 427 | partial_func = ( |
| 428 | dash_app._execute_callback( # pylint: disable=protected-access |
| 429 | func, args, cb_ctx.outputs_list, cb_ctx |
| 430 | ) |
| 431 | ) |
| 432 | |
| 433 | # Run in new event loop (handles both sync and async callbacks) |
| 434 | def run_callback(): |
| 435 | result = partial_func() |
| 436 | if inspect.iscoroutine(result): |
| 437 | return asyncio.run(result) |
| 438 | return result |
| 439 | |
| 440 | response_data = ctx.run(run_callback) |
| 441 | return {"status": "ok", "data": json.loads(response_data)} |
| 442 | |
| 443 | except PreventUpdate: |
| 444 | return {"status": "prevent_update"} |
| 445 | except WebsocketDisconnected: |
| 446 | return {"status": "prevent_update"} |
| 447 | except Exception as e: # pylint: disable=broad-exception-caught |
| 448 | traceback.print_exc() |
| 449 | return {"status": "error", "message": str(e)} |
| 450 | |
| 451 | return executor.submit(execute) |
no outgoing calls
no test coverage detected
searching dependent graphs…