100 lines
4.1 KiB
Markdown
100 lines
4.1 KiB
Markdown
# cbd: bundled server + client binary
|
|
|
|
## Context and problem statement
|
|
|
|
`crabidy-server` and `cbd-tui` are separate binaries: the normal setup
|
|
runs a long-lived server and attaches TUIs to it. The user wants a
|
|
single binary **`cbd`** for the one-machine case: starting it starts the
|
|
server and connects the TUI to it. Everything else works exactly the
|
|
same — same configs, same gRPC wire, same features.
|
|
|
|
## Assumptions (confirmed)
|
|
|
|
- `cbd-tui`'s config (`cbd-tui.toml`) already carries the server
|
|
address; the server listens on a constant (`0.0.0.0:50051`).
|
|
- Both mains are thin shells over module code: the server's `main.rs`
|
|
holds the command/message enums and the startup sequence; the TUI's
|
|
holds tracing setup and two loops (`orchestrate`, `run_ui`).
|
|
- The gRPC boundary stays: the bundled TUI talks to the in-process
|
|
server over localhost exactly like a remote one ("works the same
|
|
completely"). No in-process transport special-casing.
|
|
|
|
## Decisions
|
|
|
|
### D1 — Both binaries become libraries with thin mains
|
|
|
|
- **crabidy-server**: `playback`, `provider`, `rpc` move from bin
|
|
modules to lib modules; the command/message enums and the startup
|
|
sequence move into the lib (`serve(addr)` builds orchestrator, queue
|
|
store, playback, rpc service and serves tonic on `addr`). `main.rs`
|
|
keeps only stderr tracing setup + `serve(LISTEN_ADDR)`.
|
|
- **cbd-tui**: gains `src/lib.rs` exposing `run(config)` (the two loops
|
|
and their channels); `main.rs` keeps file-based tracing setup +
|
|
config init + `run`.
|
|
- Behavior-preserving: no logic changes, only module moves and
|
|
`crabidy_server::` → `crate::` path rewrites. All existing tests move
|
|
along unchanged.
|
|
|
|
Not chosen: `cbd` spawning `crabidy-server` as a subprocess — that
|
|
needs the second binary installed, which is exactly what "a single
|
|
binary" is for.
|
|
|
|
### D2 — `cbd` = start (or adopt) the server, then run the TUI
|
|
|
|
New tiny binary crate `cbd`:
|
|
|
|
1. Tracing goes to the TUI's log file for **both** halves — the
|
|
terminal belongs to the TUI, so the server's stderr logging would
|
|
corrupt it.
|
|
2. Spawn `crabidy_server::serve(LISTEN_ADDR)` on a background task.
|
|
If the port is already taken (`AddrInUse` — a standalone server is
|
|
running), log and carry on: the TUI simply connects to the existing
|
|
server. Any other server error before readiness is fatal.
|
|
3. Wait for readiness by polling a TCP connect against the configured
|
|
server address (bounded retries with delay, then a clear error).
|
|
4. Run the TUI exactly as `cbd-tui` would, with the same
|
|
`cbd-tui.toml`.
|
|
|
|
Quitting the TUI ends the process — and with it the in-process server.
|
|
That is inherent to bundling and fine: the current queue is persisted
|
|
continuously, so the next start restores it (the ≤200 ms persist
|
|
debounce window is the same loss window as killing the standalone
|
|
server).
|
|
|
|
### D3 — Out of scope (explicitly)
|
|
|
|
- An in-process (channel) transport instead of localhost gRPC.
|
|
- Daemonizing: `cbd` never outlives its TUI. Users who want a
|
|
persistent server keep running `crabidy-server`.
|
|
- CLI subcommands (`cbd server`, `cbd attach`, …) — later if wanted.
|
|
|
|
## Structure
|
|
|
|
```d2
|
|
direction: right
|
|
|
|
cbd: "cbd (one binary)" {
|
|
boot: "main: file tracing,\nspawn server, wait, run TUI"
|
|
srv: "crabidy-server lib\nserve(addr)"
|
|
tui: "cbd-tui lib\nrun(config)"
|
|
boot -> srv: "tokio::spawn\n(AddrInUse → adopt)"
|
|
boot -> tui: "after TCP readiness"
|
|
tui -> srv: "localhost gRPC\n(unchanged wire)"
|
|
}
|
|
|
|
standalone: "crabidy-server bin\n(unchanged)"
|
|
remote: "cbd-tui bin\n(unchanged)"
|
|
remote -> standalone: "gRPC (remote setup\nkeeps working)"
|
|
```
|
|
|
|
## Risks and open questions
|
|
|
|
- **Port constant**: the server listens on `0.0.0.0:50051` and the TUI
|
|
config defaults to localhost; if the user points `cbd-tui.toml` at a
|
|
remote server, `cbd` still starts a local one (and connects to the
|
|
configured, remote one). Accepted: `cbd` is the one-machine tool.
|
|
- **Two log producers, one file**: server and TUI layers share the
|
|
bundled tracing subscriber; targets distinguish them.
|
|
- Open (future): a `--no-server` flag; graceful server shutdown (flush
|
|
the persister) on TUI exit.
|