Я хочу использовать сервер Bokeh для создания графического просмотра в прямом эфире для моих данных. Я хочу получить данные в одном потоке, а затем передать их всем открытым документам /сеансам.
Что было бы хорошим решением для этого? Есть ли даже хорошее решение? Кроме того, после загрузки страницы существуют только начальные данные, видимые до появления новых данных. < /P>
Код: Выделить всё
# app_hooks.py
import time
import threading
import bokeh.server.contexts
from bokeh.plotting import Document
from bokeh.models import ColumnDataSource
keep_running = True
data = { # some initial data
'x': [1, 2, 3, 4, 5],
'y': [6, 7, 2, 4, 7]
}
def callback(document: Document, new_data: dict):
model = document.get_model_by_name("line")
if model is None:
print("Model not found in document")
return
assert isinstance(model, bokeh.models.renderers.glyph_renderer.GlyphRenderer)
source: ColumnDataSource = model.data_source
# source.stream(new_data, rollover=100)
source.data = new_data
def retrieve_data(i: int) -> dict[str, list[float]]:
# idea: use a PUB/SUB pattern to retrieve data
global data
time.sleep(1) # it might take some time until new data is available. Can be seconds to hours.
data['x'].append(i)
data['y'].append(i * 0.5 % 5)
return data
def on_server_loaded(server_context: bokeh.server.contexts.BokehServerContext):
# If present, this function executes when the server starts.
def add_data_worker():
global keep_running
i=0
while keep_running:
print(f"Iteration {i + 1}")
new_data = retrieve_data(i)
for session in server_context.sessions:
print(session.destroyed, session.expiration_requested)
session.document.add_next_tick_callback(lambda: callback(session.document, new_data))
i += 1
thread = threading.Thread(target=add_data_worker, daemon=True)
thread.start()
def on_server_unloaded(server_context: bokeh.server.contexts.BokehServerContext):
# If present, this function executes when the server shuts down.
global keep_running
keep_running = False
< /code>
# main.py
from bokeh.plotting import figure, curdoc
from bokeh.models import ColumnDataSource
from .app_hooks import data
source = ColumnDataSource(data=data)
p = figure(title="Simple Line Example", x_axis_label='x', y_axis_label='y')
p.line(x="x", y="y", legend_label="My Value", line_width=2, source=source, name="line")
curdoc().add_root(p)
< /code>
Other ideas I had:
[*]If I use a publish/subscribe pattern anyway I could create one subscriber and update-thread per session. But for me it feels better to have them centralized.
Let each session poll the data from another server. I would do so by using curdoc().add_periodic_callback(callback, 1000)
< /ul>
Есть ли другие идеи? Есть ли лучшие практики для подобных проблем? Я даже выбираю хорошую библиотеку для этого?
Подробнее здесь: https://stackoverflow.com/questions/796 ... l-sessions