I have a Dash application hosted on Heroku. Under some circumstances a callback will take more than 30 seconds to execute. Long callbacks are the suggested solution to this issue.
But before implementing long callbacks, it would be good to at least let the user know that the server has timed out. As described in this recent feature request, there is no way in Dash to catch the server timeout, in order to report the situation to the user.
I thought perhaps the callback could anticipate the timeout using signal.alarm(), as suggested by a post over on stackoverflow. My attempt:
import signal import dash import dash.dependencies as dd # From https://stackoverflow.com/a/25027182/2076081 class TimeoutException(Exception): # Custom exception class pass def timeout_handler(signum, frame): # Custom signal handler raise TimeoutException # Change the behavior of SIGALRM signal.signal(signal.SIGALRM, timeout_handler) @app.callback( dd.Output('results', 'data'), dd.Output('explanation', 'children'), dd.Input('parameters', 'data') ) def _run_model_with_timeout(parameters): signal.alarm(30) try: results = _run_model(parameters) except TimeoutException: return dash.no_update, "Timed out" else: signal.alarm(0) # turn off the alarm return results, "Run complete"
Sadly this did not work. I tried it on my local (MacOS) server, before trying on Heroku. Instead of catching the TimeoutException within the callback, the exception is raised elsewhere, and uncaught.
Is there any way a callback could learn that something takes more than 30 seconds?