Update UI from the server

I am writing a simulation application that reads in data from a database, configures the simulation, runs it in the cloud, and then retrieves and plots the result.
It also gets notified of changes to the database so it can update the UI.
Simulation duration ranges from nearly instantaneous to multiple days.

So I’m building this dashboard app thingy for configuring the simulation and plotting the results.
Due to the wide range of simulations, I want to be able to run the UI by itself for simple simulations, in a notebook for custom scripting, or as a script that just saves the output.

The part I’m having trouble with is updating the UI when an external change happens.
All the examples I can find use client-initiated updates, like you drag a slider and that updates the plot.
In my case, the update is external, from the database or the simulation server.

I have found bokeh/Continuous Updating.ipynb at main · bokeh/bokeh · GitHub which allows you to update the plot using the notebook-specific notebook_push function. So this is a great start, but as I said I’d also like to run the UI outside the notebook.

Running the basic sliders.py example, it appears as if it’s just a normal callback that updates the plot, which works perfectly. But, when I try to change anything outside a UI-initiated event it doesn’t work. I’ve added the following code as a demonstration:

def update():
    plot.title.text = "update!!"


This gives me a RuntimeError: _pending_writes should be non-None when we have a document lock, and we should have the lock when the document changes so it’s obviously not as simple.

Is there a portable way to update the UI from a server-initiated event like a database update?

Please see: Running a Bokeh server — Updating from Threads