Subject: Re: bug#61350: Eglot over Tramp freezes with large project

From: João Távora <[email-masked]>
Date: Thu, 16 Mar 2023 22:04:57 +0000

On Thu, Mar 16, 2023 at 8:36 PM Stefan Monnier <[email-masked]> wrote:

> I think doing more of the work asynchronously (i.e. from the process's
> filters/sentinels rather than after `accept-process-output`), like in
> this example, is virtually always better, yes.
>
> The use of `catch/throw` is not applicable to code which may be used
> asynchronously (i.e. where we don't know that there's always a `catch`
> waiting for our `throw`), so I hope we can get code to work just as
> reliably without using `catch/throw`.

Of course, normally you want the async/sync pair of primitives:

(defun hal-async-command (callback)
  "Send command, call CALLBACK."
  (when (process-get hal-proc 'callback)
     (error "HAL only takes one command at a time")
  (process-put hal-proc 'callback callback)
  (process-send-string hal-proc "OPEN THE POD BAY DOORS!\n"))

(defun hal-sync-command ()
  (catch 'hal-done
     (hal-async-command (lambda (r) (throw 'hal-done r))))

So what I mean is:

* when synchronous APIs are needed (that is presumably what TRAMP needs,
  according to you) then *do* use catch/throw/filter/accept-process-output

* when async is needed, use callbacks.

You can mix in the upcoming emacs-io.el/futur.el/whatever frameworks,
but when processes are involved, some variation on that technique
should be used somewhere.

My main point here is that this bug's root cause is the lack
of good filter+accept-process-output design.  I just think that
basic tools to achieve that design are already in place and
reasonably easy to grasp.  I'm not opposed to newer tools.

And I already mentioned that the above approach can be
enhanced to include timeouts and cancellation on user input
(for the latter, sit-for is usually preferable to a-p-o).

> This mission is too important for me to allow you to jeopardize it.

:-) Sorry to interrupt the festivities, Dave

João