Hi,
In the process of writing some notes below for you I think I see why this may be happening, tho I am not all sure then why it would seem not to happen for me on OSX. Will take some investigation and I am not sure what we might be able to do about it.
TLDR: This decorator:
https://github.com/bokeh/bokeh/blob/master/bokeh/server/session.py#L47
collects all the pending writes that would happen as a result of a callback, then yields them all in sequence after the callback is executed. See below for the gory details.
### Notes (started writing these first then added the note above)
It sounds like this will require some investigation. I'm currently most familiar with these code paths, but even I don't have to get into them very often, that part of the project is very well covered in tests and does not change often. I'm traveling currently, so I won't be able to dig in to this immediately, but if you want to poke around, here's a rough idea of the code paths:
* Document._notify_change
https://github.com/bokeh/bokeh/blob/master/bokeh/document/document.py#L988
This gets invoked when any model's property changes. This is true and independent of a Document being used with the server, but it is most used/useful in the context of the bokeh server
* Document.on_change_dispatch_to
https://github.com/bokeh/bokeh/blob/master/bokeh/document/document.py#L667
The Session calls this on its Document, with itself as the target, to make sure any changes get routed to it to handle.
The exact hook up to the next step is a bit confusing, there is simple multiple dispatch mechanism that obscures the codepaths somewhat. But the end result is that those change events trigger this method:
* Session._document_patched:
https://github.com/bokeh/bokeh/blob/master/bokeh/server/session.py#L210
The session is basically the bridge between a Document and the connection to the browser. This method tells the connection to generate a wire protocol message for the changes (to send to BokehJS) and appends a future that can send that message, to a list of pending writes
* Connection.send_patch_document
https://github.com/bokeh/bokeh/blob/master/bokeh/server/connection.py#L74
This is where there protocol message generation and the yield message.send come from
So where/when do those pending writes actually get processed? There is a "document lock" decorator that was applied to all the session callbacks:
https://github.com/bokeh/bokeh/blob/master/bokeh/server/session.py#L47
That decorator collects all the writes during a callback, and then yields them...Oh that actually seems like it would explain what you are seeing.. I will add a note up top...
For reference, that decorator gets applied via here:
https://github.com/bokeh/bokeh/blob/master/bokeh/server/session.py#L123
Thanks,
Bryan
···
On May 2, 2019, at 9:12 AM, [email protected] wrote:
Hi Bryan,
Thanks for the response. This was originally happening on Windows 10 with Python 3.6 and Bokeh 1.0.4. I have also been able to replicate same issue with the above example on Windows 10, Python 3.7 and Bokeh 1.1.0 and on (k)ubuntu 19.04, Python 3.7, Bokeh 1.1.0.
This happens when I use either Chrome, Firefox or Edge, although I don't think it's a front end problem. Looking at the web socket messages, the server sends the fast and slow updates at (essentially) the same time (see attached image):
Does Bokeh use some os-level interface to batch events? That would explain why OSX would be doing something different that Windows and Linux. I couldn't find where in the source code that the batching happens, but if you point me to it I can help explore this.
Thanks,
Linus
On Wednesday, May 1, 2019 at 4:56:10 PM UTC-4, Bryan Van de Ven wrote:
Hi,
Please provide version/platform information. When I try this code on master (1.1.1dev) on OSX/Safari I see the fast update immediately, and the slow update two seconds later.
Thanks,
Bryan
> On Apr 30, 2019, at 12:13 PM, lmar...@gmail.com wrote:
>
> from time import sleep
>
> from bokeh.io import curdoc
> from bokeh.layouts import column
> from bokeh.models.widgets import Select, Div
>
> INITIAL = 'Option1'
>
> select = Select(
> options=['Option1', 'Option2', 'Option3'],
> value=INITIAL
> )
>
> div_1 = Div(text=INITIAL)
> div_2 = Div(text=INITIAL)
>
>
> def select_change(attr, old, new):
> div_1.text = '{} (fast update)'.format(new)
>
> # stand-in for a long-running calculation
> sleep(2)
>
> div_2.text = '{} (slow update)'.format(new)
>
>
> select.on_change('value', select_change)
>
> layout = column(select, div_1, div_2)
>
> curdoc().add_root(layout)
--
You received this message because you are subscribed to the Google Groups "Bokeh Discussion - Public" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/d024a41c-9719-47e5-902c-cf537ec4c406%40continuum.io\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.
<Bokeh ws.PNG>