英文:
Force update on bokeh server start
问题
以下是要翻译的内容:
I have an application running on a Bokeh Server which renders data.
The computation of the data is somewhat costly, and I want to show a loading screen while it is done.
When the server has opened and I am changing parameters, this works out fine so far using curdoc().add_next_tick_callback()
as described in https://stackoverflow.com/questions/60745065/force-update-of-bokeh-widgets.
However, when a document is opened initially (that is, when I open http://localhost:5006/my_application
), the delay does not work at all.
My current attempt is basically (simplified):
main.py:
from bokeh.plotting import curdoc
from main_frame import MainFrame
print('start')
# the constructor contains code to create a loading screen
main_frame = MainFrame()
curdoc().add_root(main_frame.layout)
curdoc().add_next_tick_callback(lambda: main_frame.plot('initial_file_name'))
print('after adding callback')
If I remove the last line, the loading screen shows as it should, but obviously no computation is done.
With the last line, the initial data is shown without first showing the loading screen during computation.
I have some console output in the computation, and it clearly shows that the computation is done before the connection is created:
Initial startup:
> bokeh serve my_application
2023-03-15 14:27:32,064 Starting Bokeh server version 2.4.3 (running on Tornado 6.1)
2023-03-15 14:27:32,064 User authentication hooks NOT provided (default user enabled)
2023-03-15 14:27:32,064 Bokeh app running at: http://localhost:5006/my_application
2023-03-15 14:27:32,064 Starting Bokeh server with process id: 5368
When http://localhost:5006/my_application
is opened:
start
after adding callback
<output from my computation>
2023-03-15 14:28:36,984 WebSocket connection opened
2023-03-15 14:28:36,984 ServerConnection created
What I would have expected:
start
after adding callback
2023-03-15 14:28:36,984 WebSocket connection opened
2023-03-15 14:28:36,984 ServerConnection created
<output from my computation>
Is there some trick to get things working?
Edit: I tried out using
curdoc().add_timeout_callback(lambda: main_frame.plot('initial_file_name'), 1000)
instead of the next tick callback as a test, and this actually shows the loading screen part for a short moment, and also has the console output like I expected.
Does that mean the code above basically works fine and it just takes longer to initially render the server than my computation takes?
[It takes less than a second, but human-notably long.]
Edit: I did another test and used a plotting input that takes a good deal longer [about three seconds]. With the next tick callback, the loading screen is still not shown.
For the timeout callback, this is quite peculiar: it only shows the loading screen when I have some minimal timeout value. A value of 500 does not result in the loading screen being shown, a value of 800 does. In both cases there is a notable delay afterwards during which the computation runs. My suspicion is that the initial rendering takes between 500 and 800 ms and it only works if the plotting is delayed after that.
Obviously using the timout callback would be a horrible solution.
英文:
I have an application running on a Bokeh Server which renders data.
The computation of the data is somewhat costly, and I want to show a loading screen while it is done.
When the server has opened and I am changing parameters, this works out fine so far using curdoc().add_next_tick_callback()
as described in https://stackoverflow.com/questions/60745065/force-update-of-bokeh-widgets.
However, when a document is opened initially (that is, when I open http://localhost:5006/my_application
), the delay does not work at all.
My current attempt is basically (simplified):
main.py:
from bokeh.plotting import curdoc
from main_frame import MainFrame
print('start')
# the constructor contains code to create a loading screen
main_frame = MainFrame()
curdoc().add_root(main_frame.layout)
curdoc().add_next_tick_callback(lambda: main_frame.plot('initial_file_name'))
print('after adding callback')
If I remove the last line, the loading screen shows as it should, but obviously no computation is done.
With the last line, the initial data is shown without first showing the loading screen during computation.
I have some console output in the computation, and it clearly shows that the computation is done before the connection is created:
Initial startup:
> bokeh serve my_application
2023-03-15 14:27:32,064 Starting Bokeh server version 2.4.3 (running on Tornado 6.1)
2023-03-15 14:27:32,064 User authentication hooks NOT provided (default user enabled)
2023-03-15 14:27:32,064 Bokeh app running at: http://localhost:5006/my_application
2023-03-15 14:27:32,064 Starting Bokeh server with process id: 5368
When http://localhost:5006/my_application
is opened:
start
after adding callback
<output from my computation>
2023-03-15 14:28:36,984 WebSocket connection opened
2023-03-15 14:28:36,984 ServerConnection created
What I would have expected:
start
after adding callback
2023-03-15 14:28:36,984 WebSocket connection opened
2023-03-15 14:28:36,984 ServerConnection created
<output from my computation>
Is there some trick to get things working?
Edit: I tried out using
curdoc().add_timeout_callback(lambda: main_frame.plot('initial_file_name'), 1000)
instead of the next tick callback as a test, and this actually shows the loading screen part for a short moment, and also has the console output like I expected.
Does that mean the code above basically works fine and it just takes longer to initially render the server than my computation takes?
[It takes less than a second, but human-notably long.]
Edit: I did another test and used a plotting input that takes a good deal longer [about three seconds]. With the next tick callback, the loading screen is still not shown.
For the timeout callback, this is quite peculiar: it only shows the loading screen when I have some minimal timeout value. A value of 500 does not result in the loading screen being shown, a value of 800 does. In both cases there is a notable delay afterwards during which the computation runs. My suspicion is that the initial rendering takes between 500 and 800 ms and it only works if the plotting is delayed after that.
Obviously using the timout callback would be a horrible solution.
答案1
得分: 0
成功解决了。
工作代码:
from bokeh.plotting import curdoc
from bokeh.events import DocumentReady
from main_frame import MainFrame
main_frame = MainFrame()
curdoc().add_root(main_frame.layout)
def render_initial(event):
main_frame.plot('initial_file_name')
curdoc().on_event(DocumentReady, render_initial)
英文:
Managed to solve it myself.
Working code:
from bokeh.plotting import curdoc
from bokeh.events import DocumentReady
from main_frame import MainFrame
main_frame = MainFrame()
curdoc().add_root(main_frame.layout)
def render_initial(event):
main_frame.plot('initial_file_name')
curdoc().on_event(DocumentReady, render_initial)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论