Commit graph

81 commits

Author SHA1 Message Date
Nathaniel Nicandro
22d2a3f327 Remove the jupyter-send method...
- Add a `message-publisher` slot to `jupyter-request`, set when
  sending a request.

- `*-request` functions now return a delayed request value instead of
  a request. Update call sites.

- Add the functions `jupyter-messages`, `jupyter-idle`,
`jupyter-message-subscribed` and `jupyter-client-subscribed`.

- Move client subscription to a request's messages to
  `jupyter-client-subscribed`.

- Request callbacks are now added via `jupyter-message-subscribed`.

- Reduce usage of callbacks in favor of searching `jupyter-messages`
  where appropriate.

- Update tests
2023-02-13 20:25:05 -06:00
Nathaniel Nicandro
bbb32457a9 Remove requests slot of a client 2023-02-13 20:25:05 -06:00
Nathaniel Nicandro
b46cf42aa3 Remove jupyter-last-sent-request 2023-02-13 20:25:05 -06:00
Nathaniel Nicandro
a76d772716 (send ... (request ...)) -> (request ...) 2023-02-13 20:25:05 -06:00
Nathaniel Nicandro
dfd1d1e02d Remove the kernel slot of a client
`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.
2023-02-13 20:25:05 -06:00
Nathaniel Nicandro
134167e65e Remove keyword message types 2023-02-13 20:25:05 -06:00
Nathaniel Nicandro
548b23cba2 test/test-helper.el: Fix client cache cleanup 2023-02-13 20:25:05 -06:00
Nathaniel Nicandro
0c0ff8fb0b Fix wrong usage of jupyter-request in tests 2023-02-13 20:25:05 -06:00
Nathaniel Nicandro
a66e15277d Actually delete temporary test directory after running tests 2023-02-13 20:25:05 -06:00
Nathaniel Nicandro
67b633d52d Update jupyter-test-with-kernel-client to use a notebook kernel 2023-02-13 20:25:05 -06:00
Nathaniel Nicandro
18027386d4 Update test helpers 2023-02-13 20:22:50 -06:00
Nathaniel Nicandro
e7c0919fce Remove tests related to jupyter-kernel-process, ioloop, comm, zmq, and channels 2023-02-13 20:22:50 -06:00
Nathaniel Nicandro
9d801b72a3 Remove jupyter-connection.el 2023-02-13 20:22:50 -06:00
Nathaniel Nicandro
e133c34707 Add do prefix to launch,shutdown,interrupt functions of a kernel
launch,shutdown,interrupt are now monadic functions.
2023-02-13 20:22:50 -06:00
Nathaniel Nicandro
8f9f563afc Fix test 2023-02-13 20:22:49 -06:00
Nathaniel Nicandro
2d807d8670 Replace uses of jupyter-clients
This function is used elsewhere.
2023-02-13 20:22:49 -06:00
Nathaniel Nicandro
b5fac750e3 Remove setting of conn slot of a client in tests 2023-02-13 20:22:49 -06:00
Nathaniel Nicandro
e111aba096 Move jupyter-(dis)?connect into the jupyter-connection interface
The former pair of methods were only used to connect clients and
kernels.
2023-02-13 20:21:14 -06:00
Nathaniel Nicandro
348df7feb5 Remove jupyter-send-* methods
These methods were not used much internally.
2023-02-13 20:21:14 -06:00
Nathaniel Nicandro
8cd90fb9e0 Fix ordering of test cleanup
Stop the clients before stopping an connections to kernel servers.

* test/test-helper.el: Do it.
2023-02-13 20:21:14 -06:00
Nathaniel Nicandro
55ee3e7e46 Use jupyter-process-environment in one place
* test/test-helper.el (jupyter-test-ipython-kernel-version): Do it.
2023-02-13 20:21:14 -06:00
Nathaniel Nicandro
f2c9d5fb25 Convert jupyter-kernel into a method
* 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`.
2023-02-13 20:21:14 -06:00
Nathaniel Nicandro
61d01dfcf1 Skip some tests 2023-02-13 20:21:14 -06:00
Nathaniel Nicandro
aa6826962d Fix manager slot check during tests
`(slot-boundp client 'manager)` always returns t since the `manager`
slot defaults to `nil` for every client.  To check for a manager we
need to check for a non-nil `manager` slot.

* test/test-helper.el
(jupyter-test-with-client-cache): Check for a non-nil `manager` slot.
2023-02-13 20:21:14 -06:00
Nathaniel Nicandro
bdb8488bf3 Remove comm-layer and related
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.
2023-02-13 20:21:14 -06:00
Nathaniel Nicandro
93eeda42a6 Replace jupyter-channel-ioloop-comm internals with new impl.
* jupyter-comm-layer.el
(jupyter-comm-initialize): Remove default method.  This is in
preparation for moving over to classless communication.

* jupyter-channel-ioloop-comm (jupyter-connection): Require.
(jupyter--proxy-channel): New type.
(jupyter--make-channel-group, jupyter--channel-alive-p)
(jupyter--start-channel, jupyter--stop-channel)
(make-jupyter-async-connection): New functions.
(jupyter-channel-ioloop-comm): Remove `ioloop-class` slot, update all
callers. Remove `channels` slot, update all setters and
references. Add `conn` slot which holds a `jupyter-connection`.
(jupyter-comm-initialize): Initialize the `conn` slot to the
connection returned by `make-jupyter-async-connection`.
(jupyter-comm-start, jupyter-comm-stop)
(jupyter-comm-alive-p, jupyter-comm-id, jupyter-channel-alive-p)
(jupyter-stop-channel, jupyter-start-channel): Replace the body of these
functions with their equivalents in `conn`.

* jupyter-kernel-process-manager.el
(jupyter-make-client): Update `jupyter-channel-ioloop-comm` call.

* jupyter-repl.el:
(jupyter-connect-repl): Ditto.

* test/test-helper.el
(initialize-instance) [jupyter-echo-client]: Ditto. Replace setting of
`channel` slot with setting the `conn` clot.
2023-02-13 20:21:14 -06:00
Nathaniel Nicandro
95f3e150b4 Add jupyter-kernel.el and related
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.
2023-02-13 20:21:14 -06:00
Nathaniel Nicandro
f7292ed195 Add a jupyter-kernelspec struct
* 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.
2023-02-13 20:21:11 -06:00
Tomasz Mieszkowski
7d20c0aee2 Sort available kernelspecs; guess with ^; use guessing in jupyter-run-repl 2022-04-19 13:52:23 -05:00
Nathaniel Nicandro
c702f1e90f Add some helper functions for Org tests 2021-11-30 10:47:53 -06:00
Nathaniel Nicandro
db450a9f44 Ignore ANSI escapes when testing some Org source blocks 2021-11-30 10:47:53 -06:00
Nathaniel Nicandro
403c70c83c Bump version 2020-04-07 15:13:51 -05:00
Nathaniel Nicandro
a4e0616ed4 Revert commits making ZMQ optional
These commits were pre-maturely pushed to master.

This reverts commits:

    - 3322ce7b31
    - ee8b5180e5
    - 8883a6631a
    - ae5dad9796
    - 0e202a02fa
    - 5725215268
    - 3b3e358933
    - a5f8d991b0
    - 1a739feec7
    - 4115ff5f73
2020-04-02 10:48:44 -05:00
Nathaniel Nicandro
ee8b5180e5 Make ZMQ an optional user dependency
* 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`.
2020-03-30 23:31:14 -05:00
Nathaniel Nicandro
ae5dad9796 Split ZMQ dependent tests into test/jupyter-zmq-test.el
* test/jupyter-test.el: Move all zmq related tests (and code) to
  `test/jupyter-zmq-test.el`, add a `zmq` tag to the tests.

* test/test-helper.el (zmq, jupyter-zmq-channel-ioloop)
(jupyter-zmq-channel-ioloop-comm): Remove requires.
(jupyter-test-ioloop-eval-event, jupyter-test-channel-ioloop)
(initialize-instance) [jupyter-echo-client]: Remove uses of ZMQ by using
a `jupyter-mock-comm-layer` for the `kcomm` slot.
(jupyter-test-zmq-sockets): Move to `test/jupyter-zmq-test.el` along with all
related code.

* test/jupyter-zmq-test.el: Add tests moved from `test/jupyter-test.el` and all
  related code.
2020-03-30 23:31:14 -05:00
Nathaniel Nicandro
989e17c706 Remove unnecessary Version headers in test files
* test/jupyter-server-test.el: Do it.

* test/jupyter-test.el: Do it.

* test/jupyter-tramp-test.el: Do it.

* test/test-helper.el: Do it.
2020-03-29 03:08:53 -05:00
Nathaniel Nicandro
2e0b74c588 Remove unnecessary uses of ZMQ
* test/test-helper.el (jupyter-test-conn-info-plist)
(jupyter-test-ensure-notebook-server): Do it.
2020-03-14 14:39:35 -05:00
Nathaniel Nicandro
dcf80d51db Remove jupyter-comm--channel
Since we are using keyword to represent channels on the client level, use a
plist of channels on the comm layer level instead of channel slots. This allows
us to remove `jupyter-comm-channel` and simplify the relevant code somewhat.
2019-09-17 11:42:21 -05:00
Nathaniel Nicandro
8cca30aea3 Fix ert--print-backtrace being undefined during tests on Emacs >= 27
This is a workaround until `ert-runner` supports Emacs 27
2019-09-15 16:33:24 -05:00
Nathaniel Nicandro
4b97a72cdd Don't overwrite default url-cookie-file during tests
This is now easier to do since the value of `url-cookie-file` is propagated to
websocket subprocesses.
2019-08-11 14:22:28 -05:00
Nathaniel Nicandro
7a1c91eef4 Add the jupyter-kernel-process-manager class
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`.
2019-08-08 22:04:27 -05:00
Nathaniel Nicandro
239715919f Move server slot of jupyter-server-kernel-manager to the kernel object 2019-07-24 16:59:04 -05:00
Nathaniel Nicandro
8d45a0242d Refactor notebook server related tests
* Start notebook on-demand during tests

* Do cleanup of sockets/processes when killing Emacs

  * This should work around intermittent core dumps on Travis due to epoll
    reconnect attempts.

* Simplify tests by creating and using setup/teardown macros
2019-07-24 16:59:04 -05:00
Nathaniel Nicandro
e35981d147 jupyter-rest-api.el: Refactor login and authentication 2019-07-24 16:59:04 -05:00
Nathaniel Nicandro
194df39643 Separate tests that use a notebook server from the main tests 2019-07-24 16:59:04 -05:00
Nathaniel Nicandro
4a87d35f76 Jupyter notebook contents API integration with TRAMP 2019-07-24 16:59:04 -05:00
Nathaniel Nicandro
9df340bd0f Add REST API
* jupyter-rest-api.el: New file.

* test/jupyter-test.el (jupyter-rest-api):
(jupyter-api--copy-cookies, jupyter-api--password-login):
(jupyter-api-kernel-ws): New tests.

* test/test-helper.el (jupyter-test-rest-api): New macro.
2019-07-24 16:59:04 -05:00
Nathaniel Nicandro
6650dd3588 Bump version 2019-07-24 16:03:22 -05:00
Nathaniel Nicandro
8fc5f0bbee Make jupyter-channel-ioloop independent of zmq
This change localizes all `zmq` related functionality to `jupyter-ioloop` and
`jupyter-zmq-*` files.

* jupyter-channel-ioloop-comm.el: Add better commentary.
(jupyter-base): Require.
(jupyter-channel-ioloop-comm): Add `ioloop-class` slot
(initialize-instance [jupyter-channel-ioloop-comm]): Use it.

* jupyter-channel-ioloop.el (jupyter-base, jupyter-zmq-channel): Un-require.
(jupyter-ioloop-session, jupyter-ioloop-channels):
Rename to `jupyter-channel-ioloop-session` `jupyter-channel-ioloop-channels` and
update all callers.
(jupyter-channel-ioloop): Make into an abstract class.
(initialize-instance [jupyter-channel-ioloop]): Re-add
`jupyter-channel-ioloop-add-send-event`. Don't add to
`jupyter-ioloop-post-hook`.
(jupyter-channel-ioloop-recv-messages): Remove.
(jupyter-channel-ioloop--set-session, jupyter-ioloop-start)
(jupyter-channel-ioloop-add-send-event): Doc changes.
(jupyter-channel-ioloop-add-start-channel-event)
(jupyter-channel-ioloop-add-stop-channel-event):
Don't add/remove from the `jupyter-ioloop-poller`.
Now expected to be handled in the `jupyter-channel` subclass.
Update documentation. In addition, for the start-channel event,
do not attempt to add a channel if one doesn't already exist.

* jupyter-ioloop.el
(jupyter-ioloop-add-teardown):
Remove mention of `jupyter-channel-ioloop` behavior.
(jupyter-ioloop-add-arg-type): Update example variable.
(jupyter-ioloop-environment-p): New function.

* jupyter-kernel-manager.el (jupyter-channel): Require.
(jupyter-make-client): Require and use `jupyter-zmq-channel-ioloop`.
(jupyter-start-channels): Use `make-instance`.
(jupyter-interrupt-kernel): Remove `condition-case`. Not needed since
preventing socket blocking is now handled by `jupyter-recv`.

* jupyter-repl.el
(jupyter-connect-repl): Require and use `jupyter-zmq-channel-ioloop`.

* jupyter-zmq-channel-ioloop.el: New file.

* jupyter-zmq-channel.el (jupyter-ioloop-poller-remove)
(jupyter-ioloop-poller-add): New declares.
(jupyter-start-channel):
Add to `jupyter-ioloop-poller` when in `jupyter-ioloop-environment-p`.
(jupyter-stop-channel):
Only disconnect the socket from its endpoint instead of closing it, leave that
up to garbage collection.
Remove from `jupyter-ioloop-poller` when in `jupyter-ioloop-environment-p`.
(jupyter-recv): Handle non-blocking.

* test/jupyter-test.el
(jupyter-zmq-channel): Use non-blocking `zmq-send` since socket is no longer
closed when calling `jupyter-stop-channel`.
(jupyter-ioloop-test-eval-ioloop): Rename to `jupyter-test-ioloop-eval-event`,
update all callers, and move to `test/test-helper.el`.
(jupyter-channel-ioloop-send-event, jupyter-channel-ioloop-stop-channel-event)
(jupyter-channel-ioloop-start-channel-event): Fix tests for variable name
changes. Use `jupyter-test-channel-ioloop`. Update `jupyter-ioloop-poller`,
addition/removal from poller is now done in the `jupyter-channel` subclass by
checking `jupyter-ioloop-environment-p`.

* test/test-helper.el (jupyter-zmq-channel-ioloop): Require.
(initialize-instance [jupyter-echo-client]): Use it.
(jupyter-test-channel-ioloop): New macro.
(jupyter-test-ioloop-eval-event): New function.
2019-06-30 12:22:26 -05:00
Nathaniel Nicandro
b40b7de837 Do not depend strongly on zmq
Having the `jupyter-comm-layer` abstraction means we do not need to do so.

* jupyter-base.el (zmq): Un-require.
(jupyter-socket-types): Move to `jupyter-channels.el`.
(jupyter-session): Don't mention zmq in doc string.
(jupyter-available-local-ports, jupyter-make-ssh-tunnel): New functions.
(jupyter-tunnel-connection): Use them.

* jupyter-channel-ioloop-comm.el: New file.

* jupyter-channels.el (jupyter-messages): Un-require.
(jupyter-comm-layer, zmq): New requires.
(jupyter-socket-types): Moved from `jupyter-base.el`.
(jupyter-send, jupyter-recv):
Implementations for `jupyter-session` moved from `jupyter-messages.el`.
(jupyter-sync-channel-comm): `jupyter-comm-layer` implementation for
`jupyter-sync-channel` objects moved from `jupyter-comm-layer.el`.

* jupyter-comm-layer.el (jupyter-channel-ioloop): Un-require.
(jupyter-sync-channel-comm): Move implementation to `jupyter-channels.el`.
(jupyter-ioloop-comm): Move implementation to new file `jupyter-ioloop-comm.el`.
(jupyter-channel-ioloop-comm):
Move implementation to new file `jupyter-channel-ioloop-comm.el`.

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

* jupyter-ioloop.el (zmq): Require.

* jupyter-kernel-manager.el
(jupyter-make-client): Ensure `jupyter-channel-ioloop-comm` is required.

* jupyter-messages.el (jupyter-send)
(jupyter-recv): Moved to `jupyter-channels.el`

* jupyter-repl.el
(jupyter-connect-repl): Ensure `jupyter-channel-ioloop-comm` is required.

* test/jupyter-test.el (jupyter-available-local-ports): New test.

* test/test-helper.el (jupyter-channel-ioloop-comm): New require.
2019-06-29 10:29:55 -05:00