Container creation locks Emacs #2

Open
opened 2026-04-12 14:04:36 +00:00 by daniel · 0 comments
Owner

Summary

Running degudev-create-containers blocks Emacs for the entire duration
of container setup (potentially several minutes). The user cannot
interact with Emacs until both containers are fully provisioned.

Root cause

degudev--setup-container calls synchronous incus.el functions
sequentially:

  • incus-launch — creates the container (slow)
  • incus-exec / incus-exec-as-user — runs shell commands inside the
    container (multiple calls: user creation, package installation, git
    config, Claude settings, custom setup commands)
  • incus-add-device — mounts disk devices (multiple calls)
  • (sleep-for 5) — explicit sleep after launch

All of these use incus--run, which calls shell-command-to-string and
blocks until completion. Two full container setups run back-to-back
(reviewer then developer), compounding the problem.

Current state of incus.el

As of 2026-04-12, incus.el now provides incus--run-async, and the
interactive commands (incus-create, incus-start, incus-stop,
incus-delete) use it. However, the low-level API functions that
degudev.el depends on are still synchronous:

  • incus-exec
  • incus-exec-as-user
  • incus-add-device
  • incus-launch
  • incus-device-exists-p
  • incus-container-exists-p

Proposed approach

There are two layers to address:

1. incus.el — async variants of low-level API functions

Add async versions of the low-level functions (e.g.,
incus-launch-async, incus-exec-async, incus-add-device-async) that
accept a callback, following the pattern already established by
incus--run-async.

Alternatively, the existing functions could be made async with an
optional callback parameter (sync when omitted, async when provided).

2. degudev.el — async orchestration of container setup

degudev--setup-container must be rewritten to chain async operations
using callbacks or a sequential-async pattern. Key considerations:

  • Steps within a single container are sequential (e.g., must create the
    container before executing commands inside it).
  • The two containers (reviewer and developer) are independent and could
    be set up in parallel.
  • The sleep-for 5 after launch should be replaced with a proper
    readiness check or an async delay.
  • Progress should be reported to the user via message as each step
    completes.

Where to fix

Both packages need changes:

  • incus.el — provide async low-level API
  • degudev.el — use the async API and orchestrate steps with callbacks

Reproduction

;; This blocks Emacs for the entire duration:
(degudev-create-containers "degudev")
# Summary Running `degudev-create-containers` blocks Emacs for the entire duration of container setup (potentially several minutes). The user cannot interact with Emacs until both containers are fully provisioned. # Root cause `degudev--setup-container` calls synchronous `incus.el` functions sequentially: - `incus-launch` — creates the container (slow) - `incus-exec` / `incus-exec-as-user` — runs shell commands inside the container (multiple calls: user creation, package installation, git config, Claude settings, custom setup commands) - `incus-add-device` — mounts disk devices (multiple calls) - `(sleep-for 5)` — explicit sleep after launch All of these use `incus--run`, which calls `shell-command-to-string` and blocks until completion. Two full container setups run back-to-back (reviewer then developer), compounding the problem. # Current state of incus.el As of 2026-04-12, `incus.el` now provides `incus--run-async`, and the interactive commands (`incus-create`, `incus-start`, `incus-stop`, `incus-delete`) use it. However, the low-level API functions that `degudev.el` depends on are still synchronous: - `incus-exec` - `incus-exec-as-user` - `incus-add-device` - `incus-launch` - `incus-device-exists-p` - `incus-container-exists-p` # Proposed approach There are two layers to address: ## 1. incus.el — async variants of low-level API functions Add async versions of the low-level functions (e.g., `incus-launch-async`, `incus-exec-async`, `incus-add-device-async`) that accept a callback, following the pattern already established by `incus--run-async`. Alternatively, the existing functions could be made async with an optional callback parameter (sync when omitted, async when provided). ## 2. degudev.el — async orchestration of container setup `degudev--setup-container` must be rewritten to chain async operations using callbacks or a sequential-async pattern. Key considerations: - Steps within a single container are sequential (e.g., must create the container before executing commands inside it). - The two containers (reviewer and developer) are independent and could be set up in parallel. - The `sleep-for 5` after launch should be replaced with a proper readiness check or an async delay. - Progress should be reported to the user via `message` as each step completes. # Where to fix Both packages need changes: - `incus.el` — provide async low-level API - `degudev.el` — use the async API and orchestrate steps with callbacks # Reproduction ``` elisp ;; This blocks Emacs for the entire duration: (degudev-create-containers "degudev") ```
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/degudev.el#2
No description provided.