Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IO errors when closing a buffer that had an active async block #531

Open
NightMachinery opened this issue Apr 9, 2024 · 3 comments
Open

Comments

@NightMachinery
Copy link

NightMachinery commented Apr 9, 2024

When I close a buffer that has an ongoing async block, I get a lot of these errors:

Jupyter: I/O subscriber error: (wrong-type-argument stringp nil) [82 times]

I need a way to close all the connections of a kernel and "forget" it completely. Here is what I already have, but I don't know how to unsubscribe the active ... "websockets"?

(defun night/jupyter-forget-client (key)
    "Forget a Jupyter client session identified by KEY.
Also kill the associated REPL and object buffers."
    (interactive "sEnter session key to forget: ")

    ;; Remove the client from the `org-babel-jupyter-session-clients' hash table
    (remhash key org-babel-jupyter-session-clients)

    (when-let* ((client (gethash key org-babel-jupyter-session-clients)))
      (let ((repl-buffer (oref client buffer)))
        (message "got repl-buffer")

        ;; Kill the REPL buffer
        (when t ;; (buffer-live-p repl-buffer)
          (message "killing repl-buffer ...")
          ;; (kill-buffer repl-buffer)
          ;; If we use `kill-buffer', the kill hooks will be triggered which will ask us if we want to kill the kernel. We don't, we just want to clear the garbage and leave the kernel alone.
          (night/force-kill-buffer repl-buffer))
        ;; Kill the object buffer
        (jupyter-with-client-buffer client
          (message "got client-buffer")
          (when t ;; (buffer-live-p (current-buffer))
            (message "killing client-buffer ...")
            ;; (kill-buffer (current-buffer))
            (night/force-kill-current-buffer))))

      (message "Forgot session: %s" key)))

(defun night/force-kill-current-buffer ()
  (interactive)
  ;; [[https://emacs.stackexchange.com/questions/59348/force-kill-a-buffer][force kill a buffer? - Emacs Stack Exchange]]
  (let (kill-buffer-hook kill-buffer-query-functions)
    (kill-buffer)))

(defun night/force-kill-buffer (buffer)
  (with-current-buffer buffer
    (night/force-kill-current-buffer)))

Related:

@NightMachinery
Copy link
Author

NightMachinery commented Apr 9, 2024

One of the reasons I close buffers is because I have run sth heavy which outputs a lot of text and images. Sometimes I just need this process to finish, and I don't need to see its results in emacs (the results will be logged elsewhere by the code). In these cases, I just want to close the buffer and get rid of the active async blocks, without interrupting or killing the kernel.

@nnicandro
Copy link
Collaborator

Although it doesn't work right now, would specifying something like :results none work for you if it did work? Specifying :results none means that the source block is executed, but the results produced by the kernel are not inserted into the buffer and basically don't get processed much.

This worked previously, but doesn't anymore due to c3892b8. I assume now that :results none means a source block is being executed due to resolving some reference to it (e.g. it being used as the value of a :var header argument) which needs to happen synchronously. I have to figure out a more direct way to determine if a source block is being executed due to reference resolution to be able to get :results none :async yes working properly again.

Although specifying :results none would mean messages still get received so there would still be some underlying processing of the messages as they come in.

@NightMachinery
Copy link
Author

NightMachinery commented Apr 11, 2024

@nnicandro While :results none can be useful, it's not the ideal solution for my use case. I prefer having the flexibility to dynamically disconnect the output during execution. There are times when I want to see at least the beginning of the output to ensure that the code is on the right track. Checking the logs elsewhere is inconvenient. Moreover, as you mentioned, processing the messages will still be suboptimal, and Emacs will become slow regardless.

Additionally, I need the ability to disconnect the kernel so that I can connect to another kernel running on the same IP and port. (This is possible with SSH port forwarding shenanigans.) It allows me to run the code with different hyperparameters simultaneously.

I understand that I might be stretching the notebook interface beyond its intended use, and it would be better to refactor the code into proper scripts. However, the notebook interface offers more power and ease of use, making it an attractive choice for my current needs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants