Expand description
Best-effort, fire-and-forget IPC from the CLI to running GUI(s).
Goal: when the CLI mutates profile state (install, update, uninstall, profile create/delete, import, …), every GUI process running against the same data dir should refresh immediately — without polling, watchers, or any CPU cost when no GUI is running.
§Mechanism
Each GUI process binds a Unix domain socket at a per-process path
(gui_socket_path: $XDG_RUNTIME_DIR/modde-${euid}-${pid}.sock).
The CLI calls notify_refresh, which enumerates the directory for
every socket matching the current user’s prefix and pushes a one-line
payload to each. Sockets that don’t accept (peer crashed without
unlinking, kernel returned ECONNREFUSED) are GC’d in the same pass.
There is no protocol: the existence of any byte-stream connection is the signal. Each GUI re-reads the DB on receipt.
§Multi-window
Per-process sockets give us natural fan-out — N GUIs ⇒ N sockets ⇒
N notifications, all from one CLI call. Each GUI is responsible for
unlinking its own socket on shutdown via cleanup_socket; the
CLI’s GC pass handles the case where a GUI crashed without doing so.
§Costs
- GUI idle: 0.
accept().awaitis a blocked syscall. - GUI active, no CLI: 0.
- CLI op, no GUI: one
read_dir+ zero connects (no socket files). - CLI op, N GUIs: one
read_dir+ N short Unix-socket round trips.
Functions§
- cleanup_
socket - Best-effort cleanup: unlink the socket file the current process bound at startup. Safe to call from drop / signal handlers / atexit.
- gui_
socket_ path - Path each GUI process binds. Includes the pid so multiple GUIs run side-by-side without colliding.
- notify_
refresh - Notify every running GUI (if any) that profile state has changed.
- notify_
refresh_ at notify_refreshfor a single explicit socket path. Exposed for tests. Returnstrueiff the payload was written successfully.- notify_
refresh_ in notify_refreshscoped to an explicit directory. Useful for tests that don’t want to mutateXDG_RUNTIME_DIR, and for instance-isolated CLI invocations that pass a custom data dir.- socket_
dir - Directory we drop sockets into.
$XDG_RUNTIME_DIRwhen present (the systemd-managed per-user tmpfs, cleaned at logout); falls back to/tmp. Callers should not assume the directory is private.