It expects a kernel ID as a second argument, not a kernel spec as
would be returned by `jupyter-server-repl-interactive-spec`.
Remove `jupyter-server-repl-interactive-spec` since it's not general
enough to handle both `jupyter-(run|connect)-server-repl`.
`jupyter-websocket-io` now returns, in addition to an IO function, a
kernel action subscriber. A client now sends messages to the
subscriber to interrupt or shutdown a kernel instead of doing so using
a `kernel` slot.
Also add the `jupyter-kernel-action` convenience function for
evaluating arbitrary code on a client's kernel.
* jupyter-kernel-process.el
* jupyter-server-kernel.el (jupyter-kernel): New method.
* jupyter-kernel.el (jupyter-kernel): Convert. Load files that handle
keywords and re-dispatch when ARGS does not have any connection
info. Document behavior.
* test/test-helper.el (jupyter-test-with-kernel-client)
* jupyter-server.el
(jupyter-connect-server-repl)
(jupyter-server-start-new-kernel): Use `jupyter-kernel`.
Remove `jupyter-channel-ioloop-comm.el`, `jupyter-comm-layer.el`, `jupyter-ioloop-comm.el`.
Remove the kcomm slot of a client, replace it with a kernel slot.
jupyter-server.el: Remove kernel communication related code.
Remove `jupyter-kernel-lifetime`.
* jupyter-kernel-manager.el (jupyter-kernel-lifetime): Do it. Update
all subclasses. All methods it defined no longer take a type. This
is in preparation of removing most of them altogether.
(jupyter-kernel-manager): Update doc.
* jupyter-kernel-process-manager.el
(jupyter-kernel-process): Update documentation.
(jupyter--kernel-died-process-sentinel): Remove type check.
* test/jupyter-test.el (jupyter-local-tcp-conn-info): Remove.
(jupyter-kernel-lifetime): Remove.
[conn] Have `jupyter-kernel-manager.el` re-direct to the new interface
* jupyter-kernel-manager.el
(jupyter-kernel-alive-p): Check that the kernel is
live, not an Emacs connection to it.
(jupyter-start-kernel)
[jupyter-kernel, jupyter-kernel-manager]: Use `jupyter-launch`.
(jupyter-shutdown-kernel) [jupyter-kernel-manager]: Use `jupyer-shutdown`.
(jupyter-kill-kernel) [jupyter-kernel]: Ditto. Remove a method
definition.
(jupyter-make-client): Use `jupyter-client`.
(jupyter-interrupt-kernel) [jupyter-kernel-manager]: Use `jupyer-interrupt`.
* jupyter-kernel-process-manager.el: Remove.
Don't add finalizer to cleanup process.
Cleanup is done in other ways, e.g. in
`jupyter--gc-kernel-processes`. Also it doesn't make sense to delete
a general kernel because the object that represents it in Emacs is no
longer accessible.
This commit removes the `jupyter-comm-layer` dependency of
`jupyter-server`.
* jupyter-server.el
(jupyter-connection): Require.
(jupyter-ioloop-comm): Remove require.
(jupyter-server): Remove the superclass. Add `ioloop` and `handlers`
slot to compensate.
(jupyter-gc-servers)
(jupyter-server-kernel-connected-p)
(jupyter-server--connect-channels)
(jupyter-server--disconnect-channels): Use the `ioloop` slot and
related methods instead of `jupyter-comm-layer` methods.
(jupyter-server--refresh-comm): Ditto, but replace the
`jupyter-comm-start` call with `jupyter-server--start-comm`.
(jupyter-event-handler): Transfer to `ioloop` slot initialization in
`jupyter-server--start-comm`.
(jupyter--server-event-handler): New type. The `handlers` slot is
a list of these.
(jupyter-server--start-comm): Initialize `ioloop` slot. All unhandled
events received on `ioloop` are passed to the handlers in `handlers`.
This commit has `jupyter-server-kernel-comm` use the new
`jupyter-connection` interface.
* jupyter-server.el
(jupyter-server-kernel-comm): Add `conn` slot.
(jupyter-server--connect-channels): Group with the new interface.
(jupyter-comm-start, jupyter-comm-add-handler)
(jupyter-comm-remove-handler) [jupyter-server]: Remove.
(jupyter-server--start-comm, jupyter--disconnect-channels)
(make-jupyter-server-connection): New functions. What the
removed functions did, these do.
(jupyter-comm-start, jupyter-comm-id, jupyter-comm-stop)
(jupyer-send, jupyter-comm-alive-p) [jupyter-server-kernel-comm]:
Replace the body of these with their equivalent in the new interface.
In `jupyter-comm-start`, set the `conn` slot to the connect returned
by `make-jupyter-server-connection` before starting the connection.
The new files added in this commit will eventually replace the manager
and kernel classes and favor struct types to represent kernels instead
of classes. A kernel manager was a concept ripped from the
jupyter/jupyter_client reference implementation.
In Emacs the concept makes the client implementation more complicated
and is replaced by functions that manage the lifetime of a kernel:
`jupyter-launch`, `jupyter-shutdown`, and `jupyter-interrupt`.
* jupyter-kernel-manager.el
* jupyter-kernel-process-manager.el
* jupyter-server.el
* test/jupyter-server-test.el
* test/test-helper.el: Make `jupyter-kernel`, `jupyter-server-kernel`,
and `jupyter-kernel-process` private classes. The new files below
use the public names, but as structs now.
* jupyter-kernel.el
* jupyter-kernel-process.el
* jupyter-server-kernel.el: New files.
* jupyter-kernel-manager.el (jupyter-kernel): Set `spec` slot type to
`jupyter-kernelspec`.
(jupyter-kernel-name):
* jupyter-kernel-process-manager.el: Update all accessors.
* jupyter-kernelspec.el: Add `jupyter-kernelspec` struct type.
* jupyter-repl.el:
* jupyter-server.el:
* ob-jupyter.el:
* test/test-helper.el: Update all kernelspec using functions to use
the new type.
The `jupyter-kill-kernel` of a kernel manager serves no purpose, just
use `jupyter-shutdown-kernel`.
* jupyter-kernel-manager.el
(jupyter-kill-kernel) [jupyter-kernel-manager]: Remove.
* jupyter-server.el (jupyter-kill-kernel) [jupyter-server-kernel-manager]: Remove.
The implementations are really aliases of `jupyter-comm-alive-p` so
keep that one instead. The `jupyter-channels-running-p` method is a
remnant of an older design, still used by `jupyter-kernel-client'
though.
* jupyter-channel-ioloop-comm.el: Do it.
* jupyter-server.el: Do it.
* jupyter-server.el (jupyter-ioloop, jupyter-server-ioloop): Remove requires.
(jupyter-server): Don't subclass `jupyter-ioloop-comm`.
(jupyter-server--connect-channels, jupyter-server--refresh-comm): Only do
something when the SERVER argument is a `jupyter-comm-layer`, i.e. a
`jupyter-server-ioloop-comm`. We don't check for that class directly since we
would end up requiring ZMQ.
(jupyter-comm-start) [jupyter-server-kernel-manager]: Use the right subclass of
`jupyter-server-abstract-kcomm` depending on if the `jupyter-server` object is
using ZMQ for communication.
(jupyter-server-make-instance): New function. Returns a `jupyter-server`
instance (a `jupyter-server-ioloop-comm`) that uses ZMQ if
`jupyter-server-use-zmq` is non-nil, and a plain old `jupyter-server` instance
otherwise.
(jupyter-current-server): `jupyter-server` -> `jupyter-server-make-instance`.
* ob-jupyter.el (org-babel-jupyter--server-repl): `jupyter-server` ->
`jupyter-server-make-instance`.
* test/test-helper.el (jupyter-test-with-notebook): `jupyter-server` ->
`jupyter-server-make-instance`.
The `jupyter-server-kernel-comm` class is re-purposed for this, as mentioned in
the previous commit.
* jupyter-server.el (jupyter-server--ws-on-message): New function.
(jupyter-comm-start, jupyter-comm-stop, jupyter-comm-alive-p, jupyter-send)
[jupyter-server-kernel-comm]: New methods.
In the following, accept means moved from `jupyter-server.el` and move means
moved to `jupyter-server-ioloop-comm.el`. A label like [class] means the
references that appear before the label are actually methods of class.
* jupyter-server.el: Move all `jupyter-event-handler` methods.
(jupyter-server-kernel-comm): Add `ws` slot. The class has
been repurposed for communication using a websocket in the current Emacs
instance. The old behavior has been assigned to the
`jupyter-server-ioloop-kernel-comm` class.
(jupyter-comm-id, jupyter-server-name-client-kernel)
(jupyter-channel-alive-p, jupyter-channels-running-p)
(jupyter-server-kernel-manager, jupyter-current-server): Rename
`jupyter-server-kernel-comm` to `jupyter-server-abstract-kcomm`.
(jupyter-server-kernel-connected-p): Redefine as a generic function. Move the
method body.
(jupyter-comm-start, jupyter-connect-client)
(jupyter-disconnect-client) [jupyter-server]: Move.
(jupyter-comm-start, jupyter-comm-stop)
(jupyter-send, jupyter-comm-alive-p) [jupyter-server-kernel-comm]: Move.
* jupyter-server-ioloop-comm.el: Accept moved `jupyter-event-handler`
methods. Rename `jupyter-server` to `jupyter-server-ioloop-comm`. Rename
`jupyter-server-kernel-comm` to `jupyter-server-ioloop-kernel-comm`.
(jupyter-server-kernel-connected-p)
(jupyter-comm-start, jupyter-connect-client)
(jupyter-disconnect-client) [jupyter-server]: Accept.
(jupyter-comm-start, jupyter-comm-stop)
(jupyter-comm-alive-p, jupyter-send) [jupyter-server-kernel-comm]: Accept.
* jupyter-server-ioloop-comm.el: New file.
* jupyter-server.el (jupyter-server-use-zmq): New variable.
(jupyter-server-abstract-kcomm): New class.
(jupyter-server-kernel-comm): Inherit from it. This is in preparation of
re-purposing the class in a future commit.
The following changes are made:
`jupyter-initialize-connection` -> `jupyter-comm-initialize`
`jupyter-connect-client` -> `jupyter-comm-add-handler`
`jupyter-disconnect-client` -> `jupyter-comm-remove-handler`
`jupyter-comm-client-loop` -> `jupyter-comm-handler-loop`
* README.org: Do it.
* jupyter-channel-ioloop-comm: Do it.
* jupyter-client.el: Do it.
* jupyter-comm-layer.el: Do it.
(jupyter-comm-layer): Rename `clients` slot to `handlers`. Update all uses.
* jupyter-kernel-process-manager.el: Do it.
* jupyter-repl.el: Do it.
* jupyter-server.el: Do it.
* jupyter-zmq-channel-comm.el: Do it.
* test/jupyter-server-test.el: Do it.
* test/jupyter-test.el: Do it.
* jupyter-server.el (jupyter-server--kernel-list-entries):
Add missing jupyter-time text property to activity string.
(jupyter-server-list-kernels): Set `tabulated-list-sort-key`.
* jupyter-base.el: Don't add `jupyter-server-mode--unset-client-soon` to
`server-switch-hook` at toplevel
(jupyter-server-mode-set-client): Add `jupyter-server-mode--unset-client-soon`
to `server-switch-hook` if necessary.
* jupyter-client.el: (jupyter--run-callbacks): Use `when-let`.
(jupyter--set-callback): Remove.
(jupyter--add-callback): Use `add-function`.
* jupyter-ioloop.el (jupyter-ioloop-add-arg-type): Use `setf` along with `alist-get`.
(jupyter-ioloop--replace-args): Use `pcase`.
(jupyter-ioloop--event-dispatcher): Extract out event cases into variable `user-events`.
(jupyter-ioloop--body): New function.
(jupyter-ioloop--function): Use it.
* jupyter-kernel-process-manager.el
(jupyter--kernel-died-process-sentinel)
(jupyter-stop-channels): Use `when-let`.
* jupyter-org-client.el (jupyter-org-interaction-mode): Use `cl-callf2?`.
* jupyter-server.el: Add TODO.
* jupyter-tramp.el: Remove unused function declaration.
Only do so when asking the user for a URL and no server exists at the URL
provided. See #183.
* jupyter-server.el (jupyter-server-non-existent): New error.
(jupyter-current-server): Signal `jupyter-server-non-existent` when asking the
user for a server URL and a server doesn't exist at URL.
TRAMP sets its own value of `signal-hook-function` which interferes with
`signal` data when handling errors in `condition-case` so unbind
`signal-hook-function` until we have a chance to look at `signal` data.
* jupyter-server.el (jupyter-kernel-alive-p): Use `nth`
* jupyter-tramp.el (jupyter-tramp--get-directory-or-file-model)
(jupyter-tramp-delete-directory): Unbind `signal-hook-function`.
So as to further generalize and separate out the abstract kernel manager class
from its various implementations.
* jupyter-kernel-manager.el (jupyter-meta-kernel): Fix documentation.
(jupyter-kernel-process, jupyter-command-kernel, jupyter-spec-kernel):
Move related functions and methods to `jupyter-kernel-process-manager.el`
(jupyter-kernel-manager-base): Remove class.
(jupyter-kernel-manager): Re-purpose class as the base class of all kernel
managers. The class corresponding to the old functionality is now named
`jupyter-kernel-process-manager`. Move all related functions and methods for
`jupyter-kernel-process-manager` to `jupyter-kernel-process-manager.el`.
* jupyter-kernel-process-manager.el: New file.
* jupyter-repl.el: Require `jupyter-kernel-process-manager` instead of
`jupyter-kernel-manager`.
* jupyter-server.el (jupyter-server-kernel-manager): Inherit from
`jupyter-kernel-manager` instead of `jupyter-kernel-manager-base`.
* test/jupyter-test.el (jupyter-kernel-lifetime)
(jupyter-command-kernel): Use `jupyter-kernel-process-manager` instead of
`jupyter-kernel-manager`.
* test/test-helper.el: Require `jupyter-kernel-process-manager` instead of
`jupyter-kernel-manager`.
See #161
* jupyter-rest-api.el (jupyter-api--delete-cookie):
(jupyter-api-delete-cookies): New functions.
* jupyter-server.el (jupyter-gc-servers): Do it.
* test/jupyter-server-test.el (jupyter-api-delete-cookies): New test.