强制在 Bokeh 服务器启动时进行更新

huangapple go评论62阅读模式
英文:

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(&#39;start&#39;)

# 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(&#39;initial_file_name&#39;))

print(&#39;after adding callback&#39;)

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:

&gt; 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
&lt;output from my computation&gt;
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
&lt;output from my computation&gt;

Is there some trick to get things working?

Edit: I tried out using
curdoc().add_timeout_callback(lambda: main_frame.plot(&#39;initial_file_name&#39;), 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(&#39;initial_file_name&#39;)
curdoc().on_event(DocumentReady, render_initial)

huangapple
  • 本文由 发表于 2023年3月15日 21:23:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/75745320.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定