Commit graph

118 commits

Author SHA1 Message Date
Nathaniel Nicandro
23ad05fd64 jupyter-kill-kernel: Don't unbind the session slot of a kernel
Not really sure why this was done in the first place, but a kernel can be
forcibly killed and then asked to started up again, e.g. when restarting the
kernel.
2019-06-12 23:02:45 -05:00
Nathaniel Nicandro
5ea32a70f0 Change License to GPL3 2019-05-31 09:44:39 -05:00
Nathaniel Nicandro
7bb7e46e1f jupyter-start-kernel (jupyter-command-kernel): Change wording of comment 2019-05-20 17:34:32 -05:00
Nathaniel Nicandro
db3bf0b681 Add FIXME for jupyter-shutdown-kernel 2019-05-13 12:07:22 -05:00
Nathaniel Nicandro
3705243179 jupyter-start-kernel (jupyter-kernel-process): Don't verify executable path
Doesn't work on remote hosts since `executable-find` is only meant for the
local Emacs instance.
2019-05-13 12:07:22 -05:00
Nathaniel Nicandro
dae02fa7d4 jupyter-interrupt-kernel: Don't use a signal when its not possible 2019-05-11 09:48:08 -05:00
Nathaniel Nicandro
eaf6478aa3 jupyter-make-client: Do boilerplate in less specialized methods 2019-05-11 09:48:08 -05:00
Nathaniel Nicandro
ea8176d6fa jupyter-start-new-kernel: Remove unreliable jupyter-wait-until-startup 2019-05-09 20:10:49 -05:00
Nathaniel Nicandro
099d2b6511 jupyter-start-kernel (jupyter-command-kernel): Directly use Jupyter's python
instead of relying on the `jupyter kernel` command
2019-05-09 20:10:49 -05:00
Nathaniel Nicandro
f158f10c12 jupyter-start-kernel (jupyter-kernel-process): Display process arguments 2019-05-09 19:49:45 -05:00
Nathaniel Nicandro
b715ada492 Always name method arguments
If method arguments are not named it gives rise to errors like

    `Args out of range: "", 0`

that originate in `help-function-arglist` when calling `describe-function` on
those methods.
2019-05-09 13:32:45 -05:00
Nathaniel Nicandro
3628cab446 Refactor of jupyter-kernel-manager.el
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.
2019-05-09 12:20:27 -05:00
Nathaniel Nicandro
ab79985580 Fix initialize-instance method signature 2019-05-09 10:56:02 -05:00
Nathaniel Nicandro
112769e0c6
Bump version 2019-05-04 03:31:50 -05:00
Nathaniel Nicandro
f4bf16079d jupyter-start-kernel: Don't check access time of conn. file on Windows 2019-05-04 02:33:11 -05:00
Nathaniel Nicandro
b2294dceb2 Generalize communication with a kernel
The previous mechanism to communicate with a kernel was too low level from the
perspective of a client. The client interfaced directly with the subprocess
abstraction, `jupyter-ioloop`, and had to handle all "events" that occurred in
the `jupyter-ioloop`, e.g. when a channel was started or stopped. But in
reality such events should not be the concern of a client.

A client should only care about events that are directly related to kernel
messages and not events related to the implementation details of *how*
communication occurs.

This commit abstracts out the way in which a client communicates with its
kernel by introducing a new `jupyter-comm-layer` class. The
`jupyter-comm-layer` class takes care of managing the communication channel
between a kernel and its clients as well as sending events to all registered
clients. This way, clients operate solely at the level of events on the
communication layer. All a client does is register itself to receive events on
the communication layer and send events on the layer.

* jupyter-base.el (jupyter-session-endpoints): New function.

* jupyter-client.el (jupyter-kernel-client): Remove ioloop and channels slots.
  Add kcomm slot.
(initialize-instance): Unconditionally stop channels.
(jupyter-initialize-connection): Change into a method call.
Call `jupyter-initialize-connection` on the `kcomm` slot.
(jupyter-with-client-buffer): Remove stale comment.
(jupyter-send): Call `jupyter-send` on the `kcomm` slot.
(jupyter-ioloop-handler): Remove all method definitions, replace `sent` and
`message` methods with their `jupyter-event-handler` equivalents.
(jupyter-hb-pause, jupyter-hb-unpause, jupyter-hb-beating):
(jupyter-channel-alive-p, jupyter-start-channel, jupyter-stop-channel):
(jupyter-start-channels, jupyter-stop-channels):
Replace with calls to their equivalents using the `kcomm` slot.

* jupyter-comm-layer.el: New file.

* jupyter-kernel-manager (jupyter-make-client): Set a client's `kcomm` slot to
  `jupyter-channel-ioloop-comm`.

* jupyter-messages.el (jupyter-decode-message): Use `list` directly. There
  seemed to be issues when using the new `jupyter-sync-channel-comm` due to
  using quoted lists.

* test/jupyter-test.el: Add `jupyter-comm-layer` test. Update other tests.

* test/test-helper.el: Add `jupyter-comm-layer` mock objects. Update
  `jupyter-echo-client`.
2019-04-11 20:13:44 -05:00
Nathaniel Nicandro
89fb38da05
Add jupyter-error-if-not-client-class-p 2019-04-08 12:44:48 -05:00
Nathaniel Nicandro
ad5113b9a7
jupyter-start-kernel: Better error reporting during kernel startup
See https://github.com/dzop/emacs-jupyter/issues/70#issuecomment-476940527

* jupyter-kernel-manager.el
(jupyter--kernel-sentinel): Make ignored argument optional.
(jupyter--start-kernel): Don't set the process sentinel.
(jupyter-start-kernel): Report any errors after timeout.
Set the process sentinel as a last step.
2019-03-27 14:34:27 -05:00
Nathaniel Nicandro
c0c8ac7fae
jupyter-start-kernel: Error if no valid kernelspec could be found 2019-03-22 20:10:22 -05:00
Nathaniel Nicandro
ca64ff75c5
jupyter-start-kernel: Cleanup resources on a kernel restart
When a kernel restarts, `jupyter-start-kernel` will overwrite the slots
corresponding to external resources of the old, shutdown, kernel, like the
connection file. Ensure resources are cleaned up before overwriting those
slots.
2019-03-22 20:10:22 -05:00
Dan
8004ca188f guard against nil connection file in jupyter-kernel-manager--cleanup (#67) 2019-03-22 18:25:22 -05:00
Nathaniel Nicandro
83af335166
Bump version 2019-03-14 09:29:11 -05:00
Nathaniel Nicandro
6894a73d57
Cleanup stale comments 2019-03-07 22:51:25 -06:00
Nathaniel Nicandro
67a1d9ee1d
jupyter--start-kernel: Use de-structuring in loop body 2019-02-19 10:03:03 -06:00
Nathaniel Nicandro
d4969cbfcc CHANGELOG.org: Add function to change version numbers 2019-02-14 23:05:00 -06:00
Nathaniel Nicandro
4d37b0efea
jupyter-shutdown-kernel: Forcibly kill the kernel after timeout 2019-02-12 15:35:19 -06:00
Nathaniel Nicandro
63717b9e39
Bump version 2019-02-12 09:17:06 -06:00
Nathaniel Nicandro
647f32e405 jupyter-start-kernel: Ensure runtime directory exists
`make-temp-file` tries to read the `temporary-file-directory` and fails if it
does not exist yet so ensure that it does exist. Fixes #3.
2019-02-09 09:19:00 -06:00
Nathaniel Nicandro
0a34860707
Fix package-lint errors 2019-02-07 11:17:24 -06:00
Nathaniel Nicandro
771e267034
Fix checkdoc errors 2019-02-06 22:49:41 -06:00
Nathaniel Nicandro
39fba18b06
Update kernel restart process 2019-01-18 22:02:13 -06:00
Nathaniel Nicandro
c138d35b83
Remove stale comments 2019-01-17 20:45:45 -06:00
Nathaniel Nicandro
ac2b5ccfbe
jupyter-start-new-kernel: Use default wait time when starting the kernel
`jupyter-start-kernel` defaults to `jupyter-long-timeout` which already
defaults to 10 s.
2018-12-19 20:59:31 -06:00
Nathaniel Nicandro
7e42bdd80e
jupyter-start-kernel: Create jupyter-runtime-directory is necessary
Closes #3
2018-12-10 21:45:41 -06:00
Nathaniel Nicandro
1ecd029f6c More clearly show that an error occurs if no kernel info is received
* jupyter-kernel-manager.el (jupyter--error-if-no-kernel-info): New function.
(jupyter-start-new-kernel): Use it.
2018-11-17 11:47:55 -06:00
Nathaniel Nicandro
4842ac2198 jupyter-delete-all-kernels: Remove old cleanup
`jupyter-kernel-manager--cleanup` is intended to replace what was removed.
2018-11-17 11:47:55 -06:00
Nathaniel Nicandro
fbeb0dba0b jupyter-start-kernel: Handle all return values of file-attributes 2018-11-16 05:09:52 -06:00
Nathaniel Nicandro
081f329da1 v0.6.0 2018-11-16 00:27:47 -06:00
Nathaniel Nicandro
9097464cc8 Add jupyter-delete-all-kernels
Add this to `kill-emacs-hook` to ensure that connection files are cleaned up in
a more reliable fashion. The connection files are cleaned up when the kernel
process is garbage collected, but this won't happen when killing Emacs.

* jupyter-kernel-manager.el (jupyter-delete-all-kernels): Do it.
Add to `kill-emacs-hook`.
2018-11-15 23:04:27 -06:00
Nathaniel Nicandro
823ea8adde Fix checkdoc warnings 2018-11-15 23:04:27 -06:00
Nathaniel Nicandro
5a7c083169 More reliably capture the startup message
It still sometimes isn't caught but it is more reliable. This mainly affects
testing.

* jupyter-client.el (jupyter-start-channels): Add a small delay after starting
  channels.

* jupyter-kernel-manager.el (jupyter-start-kernel): Remove superfluous delay.
2018-11-15 23:04:27 -06:00
Nathaniel Nicandro
c0e47165a9 Add instance tracker class
This is needed as opposed to eieio-instance-tracker so that we can create weak
references to objects. We don't want to have to manually delete an instance.

* jupyter-base.el (jupyter-instance-tracker): Do it.
(jupyter-all-objects): New function.

* jupyter-client.el (jupyter--clients): New variable.
(jupyter-kernel-client): Inherit from new class.
(jupyter-clients): Use jupyter-all-objects.

* jupyter-kernel-manager.el (jupyter-kernel-managers): New function.
2018-11-15 23:04:25 -06:00
Nathaniel Nicandro
134f84a59c Add object finalizer class
* jupyter-base.el (jupyter-finalized-object): New class.
(initialize-instance): New method addition.
(jupyter-add-finalizer): New method.

* jupyter-client.el (jupyter-kernel-client):
Inherit from jupyter-finalize-object.
(initialize-instance): Cleanup private buffer when client loses scope.
(jupyter-finalize): Remove.

* jupyter-kernel-manager.el (jupyter-kernel-manager):
Inherit from jupyter-finalized-instance.
(jupyter-kernl-manager--cleanup): New function.
(jupyter-finalize, jupyter-kill-kernel-managers): Remove. Update all callers.
(jupyter--kernel-sentinel): Remove MANAGER argument. Update all callers.
(jupyter--start-kernel): Remove MANAGER argument. Update all callers.
(jupyter-start-kernel): Add finalizer to kernel process to cleanup conn-file.

* jupyter-repl.el (jupyter-repl-kill-buffer-query-function):
Remove calls to jupyter-finalize.
2018-11-15 23:02:41 -06:00
Nathaniel Nicandro
3d45427eee jupyter-start-kernel: Use with-temp-file 2018-11-13 18:17:44 -06:00
Nathaniel Nicandro
9309e6c477 jupyter-start-channels: Simplify kernel manager method
* jupyter-kernel-manager: (jupyter-start-channels): Do it.
2018-11-13 18:17:44 -06:00
Nathaniel Nicandro
ff2feaab69 jupyter-shutdown-kernel: Report progress when shutting down 2018-11-13 17:47:55 -06:00
Nathaniel Nicandro
9aff88331a jupyter-start-new-kernel: Simplify
Remove the need to wrap in a progn. Un-pause heartbeat after waiting so that we
know for sure the kernel can be communicated with.
2018-11-13 17:47:55 -06:00
Nathaniel Nicandro
a82ae13438 Add jupyter-with-timeout macro
* jupyter-base.el (jupyter-default-timeout)
(jupyter-long-timeout): Moved from jupyter-client.el
(jupyter-with-timeout): Do it.

* jupyter-client.el (jupyter-wait-until): Use it.

* jupyter-kernel-manager.el (jupyter-shutdown-kernel)
(jupyter-interrupt-kernel, jupyter-start-new-kernel):
(jupyter-start-kernel): Use it.

use timeout
2018-11-13 17:46:19 -06:00
Nathaniel Nicandro
af32a3352f Promote the execution-state to be a slot of jupyter-kernel-client
* jupyter-client.el (jupyter-kernel-client): Do it.
(jupyter-run-hook-with-args-until-success): Pass client as first argument to
hooks.
(jupyter-execution-state): New convenience function.
(jupyter--set-execution-state): New helper function. Add as global IOPUB
message hook to set the execution-state slot.

* jupyter-repl.el (jupyter-repl-client): Remove execution-state slot.
(jupyter-handle-status): Don't set the execution-state slot.
(jupyter-repl-ret, jupyter-repl-interaction-mode-line): Use
jupyter-execution-state.
(jupyter-repl-initialize-hooks): Take into account changes to message hooks.

* jupyter-kernel-manager (jupyter-start-new-kernel): Update callback.
2018-11-13 17:46:07 -06:00
Nathaniel Nicandro
2ae44ebcd6 jupyter--kernel-sentinel: Kill the process buffer when the kernel process is dead 2018-11-01 01:56:58 -05:00