Make interactive commands asynchronous #1

Open
opened 2026-04-12 10:16:41 +00:00 by daniel · 0 comments
Owner

Problem

The interactive commands incus-create, incus-start, incus-stop, and incus-delete call the synchronous incus--run function, which uses shell-command-to-string. This blocks Emacs until the subprocess finishes. Container creation is the worst offender (it downloads an image), but stop and delete can also take noticeable time.

Solution

1. Add incus--run-async

Add a new internal function:

(defun incus--run-async (args callback)
  "Run incus with ARGS asynchronously.
ARGS is a list of strings (e.g., '(\"launch\" \"images:debian/13\" \"foo\")).
When the process finishes, call CALLBACK with (SUCCESS . OUTPUT)."
  ...)

Implementation notes:

  • Use make-process with a :sentinel.
  • :command should be (cons incus-executable args).
  • Collect output in a temporary buffer; parse it in the sentinel.
  • SUCCESS is non-nil when exit status is 0 and output does not match \\bError\\b (same logic as incus--run).
  • Kill the temporary buffer after invoking the callback.

The synchronous incus--run remains unchanged for quick queries (e.g., incus--parse-list, incus-container-exists-p).

2. Convert interactive commands

Convert these four commands to use incus--run-async:

incus-create
Show "Creating container NAME…" immediately. On success, show "Created container NAME from IMAGE" and refresh the list buffer. On failure, show "Failed to create NAME: OUTPUT".

incus-start
Show "Starting container NAME…" immediately. On success, show "Started NAME".

incus-stop
Show "Stopping container NAME…" immediately. On success, show "Stopped NAME".

incus-delete
The confirmation prompt (yes-or-no-p) stays synchronous. After confirmation, show "Deleting container NAME…" immediately. On success, show "Deleted NAME" and refresh the list buffer.

3. What stays the same

  • incus--run (synchronous) is unchanged.
  • incus-launch, incus-start-container, incus-stop-container, incus-delete-container (low-level API) remain synchronous.
  • incus-ls remains synchronous.
  • Concurrent async operations are allowed; no guards needed.
# Problem The interactive commands `incus-create`, `incus-start`, `incus-stop`, and `incus-delete` call the synchronous `incus--run` function, which uses `shell-command-to-string`. This blocks Emacs until the subprocess finishes. Container creation is the worst offender (it downloads an image), but stop and delete can also take noticeable time. # Solution ## 1. Add `incus--run-async` Add a new internal function: ``` elisp (defun incus--run-async (args callback) "Run incus with ARGS asynchronously. ARGS is a list of strings (e.g., '(\"launch\" \"images:debian/13\" \"foo\")). When the process finishes, call CALLBACK with (SUCCESS . OUTPUT)." ...) ``` Implementation notes: - Use `make-process` with a `:sentinel`. - `:command` should be `(cons incus-executable args)`. - Collect output in a temporary buffer; parse it in the sentinel. - SUCCESS is non-nil when exit status is 0 and output does not match `\\bError\\b` (same logic as `incus--run`). - Kill the temporary buffer after invoking the callback. The synchronous `incus--run` remains unchanged for quick queries (e.g., `incus--parse-list`, `incus-container-exists-p`). ## 2. Convert interactive commands Convert these four commands to use `incus--run-async`: `incus-create` Show "Creating container NAME…" immediately. On success, show "Created container NAME from IMAGE" and refresh the list buffer. On failure, show "Failed to create NAME: OUTPUT". `incus-start` Show "Starting container NAME…" immediately. On success, show "Started NAME". `incus-stop` Show "Stopping container NAME…" immediately. On success, show "Stopped NAME". `incus-delete` The confirmation prompt (`yes-or-no-p`) stays synchronous. After confirmation, show "Deleting container NAME…" immediately. On success, show "Deleted NAME" and refresh the list buffer. ## 3. What stays the same - `incus--run` (synchronous) is unchanged. - `incus-launch`, `incus-start-container`, `incus-stop-container`, `incus-delete-container` (low-level API) remain synchronous. - `incus-ls` remains synchronous. - Concurrent async operations are allowed; no guards needed.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
daniel/incus.el#1
No description provided.