This refactor implements a new class hierarchy to manage the lifetime of a
Jupyter kernel. The first node in this hierarchy is the
`jupyter-kernel-lifetime` class which defines a set of methods to manage the
lifetime of a kernel. An object that inherits from `jupyter-kernel-lifetime` is
stating that it has an association with a kernel and can be used to manage the
lifetime of the associated kernel.
The `jupyter-meta-kernel` class inherits from `jupyter-kernel-lifetime` and
mainly defines a `spec` slot used to hold the `kernelspec` from which a command
can be constructed to start a kernel and a `session` slot used to hold the
`jupyter-session` object that clients can use to establish communication with a
kernel once its live. Concrete classes that actually launch kernels are
intended to inherit from this class and use its slots.
`jupyter-kernel-process` manages the lifetime of a kernel started as a process
using the function `start-file-process`, `jupyter-command-kernel` calls the
`jupyter kernel` shell command to start a kernel, finally `jupyter-spec-kernel`
uses the `spec` slot to construct a shell command to start a kernel.
A `jupyter-kernel-manager` now consists of a `kernel` slot that holds a
`jupyter-meta-kernel` and a `control-channel` slot and inherits from
`jupyter-kernel-lifetime`. The `jupyter-kernel-lifetime` methods of the manager
just defer to those of `kernel` while also taking into account the
`control-channel`.
* jupyter-base.el (jupyter-write-connection-file): New function.
* jupyter-channel-ioloop.el
(jupyter-channel-ioloop-add-start-channel-event): Remove `sleep-for` call.
The startup message is not so important anymore.
* jupyter-client.el (jupyter-wait-until-startup: New function.
* jupyter-kernel-manager.el (jupyter-kernel-lifetime)
(jupyter-kernel, jupyter-kernel-process, jupyter-command-kernel)
(jupyter-spec-kernel): New classes.
(jupyter-kernel-manager): Inherit from jupyter-kernel-lifetime only and
implement its methods.
(jupyter-kernel-manager--cleanup, jupyter-kernel-managers)
(jupyter-delete-all-kernels, jupyter--kernel-sentinel)
(jupyter--start-kernel): Remove and remove related, their functionality has
been generalized in the new classes.
(jupyter-interrupt-kernel, jupyter-shutdown-kernel)
(jupyter-start-channels, jupyter-start-kernel, jupyter-kernel-alive-p)
(jupyter-kill-kernel): Refactor and implement to use the new class hierarchy.
* test/jupyter-test.el: Refactor tests to account for changes.
(jupyter-write-connect-file, jupyter-command-kernel): New tests.
* jupyter-kernelspec.el (jupyter-guess-kernelspec): New function.
This commit extracts out the IOLoop functions which are used to define an
IOLoop that send and receive messages on Jupyter channels into is own object.
* jupyter-channel-ioloop.el: New file.
(jupyter-channel-ioloop): A sub-type of `jupyter-ioloop` that sets up an IOLoop
to send/receive messages on Jupyter channels.
(jupyter-ioloop-channels):
(jupyter-ioloop-session): New variables used in `jupyter-channel-ioloop`
events.
(jupyter-ioloop-add-arg-type jupyter-channel): Moved from `jupyter-client.el`.
(jupyter-channel-ioloop-add-session): New function.
(jupyter-ioloop-start): Setup ioloop to communicate with Jupyter channels.
(jupyter-channel-ioloop-recv-messages):
(jupyter-channel-ioloop-add-start-channel-event):
(jupyter-channel-ioloop-add-stop-channel-event):
(jupyter-channel-ioloop-add-send-event): Moved from `jupyter-client.el`,
replaced jupyter-ioloop prefix with jupyter-channel-ioloop.
* jupyter-client.el: Require `jupyter-channel-ioloop` instead of
`jupyter-ioloop`.
(jupyter-kernel-client): Change type of `ioloop` to `jupyter-channel-ioloop`.
(jupyter-client--ioloop-setup-form): Remove.
(jupyter-ioloop-add-arg-type jupyter-channel): Move to
`jupyter-channel-ioloop.el`.
(jupyter-ioloop-add-start-channel-event):
(jupyter-ioloop-add-stop-channel-event):
(jupyter-ioloop-add-send-event): Move to `jupyter-channel-ioloop.el`, replace
jupyter-ioloop prefix with jupyter-channel-ioloop.
(jupyter-ioloop-start): Remove.
(jupyter-start-channels): Ensure `jupyter-ioloop-start` method of
`jupyter-channel-ioloop` is called. Set ioloop process buffer to `-buffer` slot
of client.
* jupyter-ioloop.el (jupyter-ioloop-start): Remove :before method.