Skip to main content

Module entrypoint

Module entrypoint 

Source
Expand description

Task 9 U10 — production sqryd binary entry point.

Owns the clap CLI (SqrydCli), the ordered startup / shutdown lifecycle (run()), and every run_start / run_stop / run_status / run_install_* / run_print_config dispatcher. main.rs calls sqry_daemon::entrypoint::main_impl() which parses the CLI, builds the tokio runtime, and maps every error to a POSIX sysexits.h exit code via DaemonError::exit_code(). Production sqryd binary entry point — Task 9 U10.

§Overview

This module owns the complete CLI definition and the ordered startup / shutdown lifecycle for the sqryd daemon binary. Every code path that could surface an error to the operator maps to a POSIX sysexits.h exit code via DaemonError::exit_code.

§CLI surface (§C.2)

sqryd [OPTIONS] [COMMAND]

Commands:
  start                   Start the daemon (foreground by default; --detach for detached)
  foreground              Run in the foreground (alias for `start`)
  stop                    Send daemon/stop and wait for socket to become unreachable
  status                  Print daemon status (--json for machine-readable output)
  install-systemd-user    Emit a systemd user-service unit to stdout   [Linux]
  install-systemd-system  Emit a systemd system-service unit to stdout  [Linux]
  install-launchd         Emit a launchd user-agent plist to stdout    [macOS]
  install-windows         Emit sc.exe + Task Scheduler XML to stdout   [Windows]
  print-config            Print the effective daemon configuration as TOML

Default (no command given): start with detach=false.

§Startup ordering (§C.3.1)

The foreground path follows these 17 ordered steps, each protected by RAII so every Drop runs on the success and error paths:

  1. Load DaemonConfig (honour --config / SQRY_DAEMON_CONFIG).
  2. Install tracing subscriber (gate RollingSizeAppender on NOTIFY_SOCKET absence — §G.1 m4).
  3. Create runtime_dir() with mode 0700 on Unix.
  4. [acquire_pidfile_lock] → [PidfileLock]. WouldBlockDaemonError::AlreadyRunning → exit 75.
  5. (Skip — detach path handled in run_start_detach.)
  6. Build plugin manager.
  7. WorkspaceManager::new (spawns the retention reaper).
  8. RebuildDispatcher::new.
  9. RealWorkspaceBuilder::new.
  10. [QueryExecutor::new].
  11. [CancellationToken].
  12. Install signal handlers → [SignalGuard].
  13. Pre-load pinned workspaces (log + continue on failure).
  14. IpcServer::bind.
  15. Signal ready (§C.3.1 step 15 authoritative matrix):
    • NOTIFY_SOCKET set → sd_notify(READY=1) (authoritative for systemd).
    • --spawned-by-client → close SQRYD_READY_PIPE_FD (authoritative for the parent auto-spawn path).
    • Always: touch runtime_dir/sqryd.ready (diagnostic, non-authoritative).
  16. server.run().await.
  17. RAII Drop order: IpcServer drops (stops accepting; socket file remains on disk in configured-path mode), pidfile removed + lock released by PidfileLock::Drop.

§Detach path (§C.3.2)

On start --detach (Unix only):

A. Parent acquires PidfileLock (WriteOwner). B. Parent creates a self-pipe via pipe2(O_CLOEXEC). C. Parent spawns current_exe() with ["start", "--detach", "--spawned-by-client"] and environment SQRYD_READY_PIPE_FD, SQRYD_LOCK_FD, SQRYD_PIDFILE_PATH. A pre_exec hook clears FD_CLOEXEC on both FDs and calls setsid(). D. Parent closes its write end. E. Parent polls read end up to auto_start_ready_timeout_secs:

  • EOF -> hand_off_to_adopter() + exit 0.
  • Timeout -> child.kill() (SIGKILL to specific PID via std::process::Child::kill) + exit 69. F. Grandchild reads SQRYD_LOCK_FD, wraps via [PidfileLock::adopt], reads SQRYD_READY_PIPE_FD, runs steps 2-14, closes pipe at step 15, runs server.run().

On Windows, --detach is a no-op with a WARN log (see §C.5).

§Design reference

docs/reviews/sqryd-daemon/2026-04-19/task-9-design_iter3_request.md §C, §D, §E, §G, §I, §J.

Structs§

SqrydCli
Production sqryd daemon binary.
Start
Arguments for sqryd start.

Enums§

Command
Top-level subcommands.

Functions§

main_impl
Top-level main trampoline. Calls run, prints any error to stderr, and converts the error to a POSIX exit code via DaemonError::exit_code.
run
Parse the CLI and dispatch to the appropriate run_* function.