Commit graph

281 commits

Author SHA1 Message Date
Nathaniel Nicandro
cc3719dedd Rename jupyter-client-initialize-connection to jupyter-initialize-connection
Also update the documentation.
2018-01-06 19:55:45 -06:00
Nathaniel Nicandro
bf1b1dae42 Add jupyter-default-timeout variable 2018-01-06 19:55:45 -06:00
Nathaniel Nicandro
27c588ebf4 Use slot-value instead of eieio-oref 2018-01-06 19:55:45 -06:00
Nathaniel Nicandro
2d0ef56be6 Add more documentation, clean up comments 2018-01-06 19:55:45 -06:00
Nathaniel Nicandro
01dab0e403 Take into account changes in zmq-process-start
Namely that the process objects are not associated with any buffer.
2018-01-06 19:55:44 -06:00
Nathaniel Nicandro
3509cccbda Prioritize shell messages more than others
This avoids problems with a reply message and a status idle message being
received at identical times for a request. Two messages can be received at the
same time when the fractional seconds resolution of the time stamps received
from the kernel are not high enough. If the iopub channel had a higher priority
it would mean that the idle message would be received before the reply when
they have identical time stamps. Since request objects are removed from the
client when an idle message is received this would prevent any reply callbacks
from running.

To combat this problem, prioritize the shell messages over any other type of
message.
2018-01-06 19:55:44 -06:00
Nathaniel Nicandro
9dd45c6f3e Be consistent with how other channels are stopped
Specifically move the `jupyter-channel-alive-p` check into
`jupyter-stop-channel` for the heartbeat channel.
2018-01-06 19:54:40 -06:00
Nathaniel Nicandro
b1c96bd286 Only bind json variables when calling json-read-file 2018-01-06 19:54:40 -06:00
Nathaniel Nicandro
c143557fb9 Care more about the width of lines 2018-01-06 19:54:40 -06:00
Nathaniel Nicandro
bb55075080 Remove a redundant check of jupyter-request-idle-received-p 2018-01-06 19:54:36 -06:00
Nathaniel Nicandro
5ab0534eb4 Don't use cond as a variable name 2018-01-06 19:53:46 -06:00
Nathaniel Nicandro
bcaa7ef2d7 Add jupyter-request-inhibit-handlers for convenience 2018-01-06 19:53:46 -06:00
Nathaniel Nicandro
068f09fa9e Update callback interface
- Introduce `run-handlers-p` for `jupyter-request` objects. When this field is
  non-nil, a clients `jupyter-handle-message` method will pass the message to
  the channels `jupyter-handle-message` after running any callbacks. Otherwise
  the channel handlers will not be run. This gives a way to suppress the
  channel handlers for a request.

- Also remove the use of `jupyter-callback` since `jupyter-handle-message` for
  a client just removes requests when an idle message is received. The callback
  object was used to check if a callback actually ran.
2018-01-06 19:47:47 -06:00
Nathaniel Nicandro
3c8cfee3ac Introduce the jupyter-handle-message method
This method dispatches to the appropriate message handlers based on the type of
channel passed to `jupyter-handle-message`. This method is also defined for a
`jupyter-kernel-client` in which case any callbacks for a message will be run
and then the message passed to the channel handlers.
2018-01-06 19:43:21 -06:00
Nathaniel Nicandro
bf81372d7a Update documentation of jupyter-wait-until-idle 2018-01-06 19:27:01 -06:00
Nathaniel Nicandro
745c08f0f6 Use with-timeout in jupyter-wait-until 2018-01-06 19:27:01 -06:00
Nathaniel Nicandro
bfb4f335c8 Cleanup comments, fix indentation, fix argument name 2018-01-06 19:27:01 -06:00
Nathaniel Nicandro
2d16ab4900 Refactor ioloop subprocess communication
- Only modify/access the `:jupyter-pending-requests' property of the ioloop
  subprocess through `jupyter--ioloop-pop-request' and
  `jupyter--ioloop-push-request'

- Push a message into a channels receive queue using
  `jupyter-channel-push-message'
2018-01-06 19:27:00 -06:00
Nathaniel Nicandro
e54ab6e899 Append -reply to reply message handler method names 2018-01-06 19:26:53 -06:00
Nathaniel Nicandro
a224253a46 Rename jupyter--send-encoded -> jupyter-send, jupyter--recv-decoded -> jupyter-recv 2018-01-02 13:50:12 -06:00
Nathaniel Nicandro
940594fda6 Rename jupyter-request-* to jupyter-*-request
Where `jupyter-request-*` are the `jupyter-kernel-client` request methods. This
required the underlying messages request message functions to be renamed to
`jupyter-message-*-request` from `jupyter-*-request`.
2018-01-02 13:50:08 -06:00
Nathaniel Nicandro
8d20384bf3 Remove the need to specify a client in the callback interface
- Also rename `jupyter-add-receive-callback` to `jupyter-add-callback`
2017-12-31 14:17:56 -06:00
Nathaniel Nicandro
276d7a5b53 Cleanup documentation and comments 2017-12-31 13:16:59 -06:00
Nathaniel Nicandro
557e97c179 Fix subprocess sentinel event checking 2017-12-30 23:35:04 -06:00
Nathaniel Nicandro
c3c3f7c44e No underscores 2017-12-27 21:07:36 -06:00
Nathaniel Nicandro
06fee9c57a Properly initialize kernel client with a kernel manager 2017-12-27 00:32:55 -06:00
Nathaniel Nicandro
363f59ef76 Remove time decoding from main loop in client subprocess 2017-12-27 00:32:00 -06:00
Nathaniel Nicandro
59a2a468a7 Only use control channel in kernel manager 2017-12-27 00:30:47 -06:00
Nathaniel Nicandro
a1fc86af0a Properly initialize kernel manager instances 2017-12-27 00:26:12 -06:00
Nathaniel Nicandro
33dd60942e Cleanup kernel manager 2017-12-27 00:21:20 -06:00
Nathaniel Nicandro
72fc893164 Return nil when prefix is nil in jupyter-find-kernelspec 2017-12-27 00:18:34 -06:00
Nathaniel Nicandro
a93204341a Add some defaults to a history request 2017-12-27 00:18:00 -06:00
Nathaniel Nicandro
f6a3690c59 Add some debug statements 2017-12-27 00:12:39 -06:00
Nathaniel Nicandro
d28dc7a3af Add a sentinel to the client's ioloop 2017-12-27 00:00:59 -06:00
Nathaniel Nicandro
5b2afb3ea0 [WIP] Kernel manager 2017-12-22 00:50:56 -06:00
Nathaniel Nicandro
b82665f889 Collect messages from kernel before sending to parent process
Instead of directly sending every received message to the parent emacs process
at the moment we receive it. The messages are stored in a queue. Only when we
do not receive a message from the kernel for two polling periods or when the
queue is full will the messages be sent to the parent process. When the
messages are sent, they are first sorted by their timestamp and prioritized
based on channel.
2017-12-21 18:20:35 -06:00
Nathaniel Nicandro
e0b5da2580 Just silently drop messages received that were not requested by us 2017-12-21 18:13:49 -06:00
Nathaniel Nicandro
5f5a742d3d Slots for a jupyter-kernel-client are always bound 2017-12-21 18:12:25 -06:00
Nathaniel Nicandro
df193db165 Remove message-callbacks 2017-12-19 21:54:11 -06:00
Nathaniel Nicandro
1848cc256a Properly cleanup ioloop subprocess
Also wrap loops that wait for subprocess output with timeouts
2017-12-19 18:47:57 -06:00
Nathaniel Nicandro
94636454c0 Use accept-process-output when waiting 2017-12-19 18:16:58 -06:00
Nathaniel Nicandro
cd158b2de6 Fix indentation 2017-12-19 18:13:42 -06:00
Nathaniel Nicandro
0f84618914 Introduce jupyter-request and jupyter-callback types
`jupyter-request` encapsulates a request ID, request callbacks, and a flag
variable which tells you if the kernel has sent an idle message for this
request.

`jupyter-callback` encapsulates a callback function and a flag variable
determining if the callback has run at least once. The `callbacks` field of a
`jupyter-request` is an alist mapping reply types to `jupyter-callback`
objects.

Whenever a message is sent to the kernel a new `jupyter-request` object is
created and returned from one of the `jupyter-request-*` methods. This object
holds all the required information to track a message that the kernel is
handling. When a message is received from the kernel, the client checks its
`requests` hash table for the `jupyter-request` object associated with the
message and runs any callbacks for the message and updates the flag variables
of the request and callback if necessary.

The request is considered complete and removed from the `requests` hash table
when an idle message has been received for the request and all callbacks have
run at least once. Note that this is almost surely does not handle all cases
since there may be situations where you would like a callback to run multiple
times while an idle message has already been sent.
2017-12-19 18:13:16 -06:00
Nathaniel Nicandro
3b7b6efaaa Take into account the status field of an is_complete_reply 2017-12-19 11:55:07 -06:00
Nathaniel Nicandro
a52ab008ed Properly handle shutdown messages 2017-12-19 11:54:10 -06:00
Nathaniel Nicandro
09aa179636 Implement starting/stopping channels in ioloop subprocess 2017-12-19 11:50:50 -06:00
Nathaniel Nicandro
29cd9912f0 Fix typo 2017-12-17 02:58:11 -06:00
Nathaniel Nicandro
c04998677c Implement callback which fires for all messages associated with a request
If `t` is passed as the `MSG-TYPE` argument of `jupyter-add-receive-callback`,
then it signifies that the associated callback will run for every message that
is received in response to a request.
2017-12-17 02:53:31 -06:00
Nathaniel Nicandro
1e246ee480 [WIP] Move all socket communication to a subprocess
With this new implementation, all communication between the kernel and the
client happens in a subprocess. When the client would like to send a message,
the parent emacs process generates the required plist and sends it to the
subprocess for encoding and sending to the kernel. When a message is received,
the subprocess decodes it and prints it to the pipe for the parent emacs
process to read.

This implementation also introduces the use of futures to avoid having to wait
for subprocess output when sending a message to the kernel. Every
`jupyter-request-*` function now returns a primitive future object which is
just a cons cell with the `car` equal to `:jupyter-future`. When the `cdr` of
the future is non-nil, then it is the message ID of the sent request. This acts
as a check to ensure that the message ID is available from the future object,
if the `cdr` is nil the ID is not available, but if the `cdr` is non-nil then
it is the message ID. The convenience function `jupyter-ensure-id` ensures that
the message ID is available and returns the ID.

The future acts as a stand in for the message ID of the encoded request which
will be retrieved from the subprocess once the message has been encoded and
sent to the kernel. This future object is meant to be passed to
`jupyter-add-receive-callback` and other related functions the same way as an
actual message id.
2017-12-17 02:53:15 -06:00
Nathaniel Nicandro
f5afa2ef07 Minor style and documentation changes 2017-12-16 19:02:11 -06:00