A problem can happen when two messages come in for different
comms, where the second depends on the first (for example, the
first might be a message setting the state of a widget, and the
second triggering a view creation for the widget). Since comm
message queues are independent of each other, the second message
could be executed before the first message.
This exposes a more fundamental assumption users are likely to
have that messages from python are processed synchronously.
Thanks to @dmadeka for reporting an error that led to discovering this issue.
Because the binary messages are now deserialized using the asynchronous FileReader API, we need to have some way to force the messages to still be processed in the order they are received. This patch implements a simple processing queue using promises.
multiplex on a 'channel' key in message,
rather than separate websockets.
Unlike zmq, there aren't different message patterns that require the channels to be separate.
Reduces FD count by factor of 3 and connection complexity in js.
Updated kernel.js to trigger the ``received_unsolicited_message.Kernel`` event instead. Notebook extensions can handle the event in whatever way they deem appropriate.
A notebook extension that takes advantage of this is available at https://github.com/nheijermans/nbexts.git.
Here's a brief overview of the changes:
- Display of messages from other clients can be toggled on and off from within a notebook, either using the ``<M-m>e`` keyboard shortcut in the web UI, or through the option in the "Kernel" menu.
- notebook.js controls whether messages are displayed through a callback that is invoked from kernel.js when no callbacks are available for a message.
- The UI displays ``execute_input`` messages originating from an other clients in new cells at the end of the notebook. Output messages (``execute_result`` et al.) will only be displayed if a cell exists with a matching message ID.
Pending design questions:
- Should each ``execute_input`` message cause a new cell to be created?
- Should new cells be placed at the end of the notebook, or elsewhere? If the latter, what criteria should be followed?