server

package
v1.4.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 4, 2026 License: MIT Imports: 25 Imported by: 0

Documentation

Overview

Package server implements the daemon-side handler for the anovel.v1.CoreService connect-rpc API. The Server type holds the long-lived daemon state — registered stacks, the target supervisor, the env allocator and builder, and the log hub — and exposes each RPC as a method that reads or mutates that state.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Server

type Server struct {
	// contains filtered or unexported fields
}

Server is the daemon's connect-rpc handler. It owns the daemon-side state that survives across RPC calls: the registered stacks, the per-target supervisor, the env allocator and builder, and the log hub.

func New

func New(version, socketPath string, stk []stacks.Stack, disc []*discovery.Stack, run *runner.Runner, alloc *env.Allocator, builder *env.Builder, logStore *logs.Store) *Server

New constructs a Server with every daemon-side subsystem wired up.

func (*Server) BackupVolume

BackupVolume writes a tar.zst snapshot per volume. Refuses if the service is up unless --force (which cascade-kills first).

func (*Server) ClearVolume

ClearVolume destroys volumes (auto-backups first unless --no-backup). Refuses while service is up.

func (*Server) Debug

Debug returns instructions for attaching Delve to a running go-exec target. It does not spawn dlv itself — the user runs the printed command in their own terminal so the dlv REPL is interactive and disconnects don't kill the target. (Auto-spawning dlv would require bidi streaming + raw-tty plumbing the daemon doesn't yet have.)

For container-mode targets, Debug is rejected — attaching to a containerised process needs a container-internal dlv install and a port-forward the daemon doesn't manage. Service developers can iterate in go-exec mode (the default) and graduate to container mode for integration tests.

DelvePort is a SUGGESTED port the user can pass to `dlv attach --listen=:<port>` — the daemon doesn't bind it. Chosen as `PID + 20000` (kept inside the high-but-not-privileged range) so a user debugging multiple targets gets a unique-per-PID port without allocation bookkeeping.

func (*Server) DescribeService

DescribeService returns one service by (stack, service) lookup.

func (*Server) Exec

Exec runs an arbitrary command "as if it were a sibling of the target":

  • Container mode: `podman exec <container_id> <cmd...>` — runs inside the live container, so `a-novel exec rest sh` drops you into a shell next to the rest binary. Requires the target to be RUNNING.
  • Go-exec mode: spawns the command in the target's working directory with the target's resolved env (POSTGRES_DSN, *_PORT etc.). Useful for `a-novel exec migrations psql` — psql gets the right DSN out of the box. Does not require the target to be running, just discoverable — the env builder synthesises a fresh allocation if none is current (so `a-novel exec migrations psql` works on a cold stack with infra up).

Stdout / stderr are forwarded as LOG_STREAM_STDOUT / _STDERR; the proto reuses LogStream so clients render with the same code path as logs.

func (*Server) GetEnv

GetEnv assembles the env block for one service (or every service in scope). Read-only: never allocates new ports. Variables that haven't been allocated yet appear with empty string values (so the user can see the shape without side-effects).

func (*Server) GetTopology

GetTopology renders the dependency graph as ASCII text. With Service == "", emits every service in the (default or specified) stack stacked vertically.

func (*Server) KillInfra

KillInfra refuses if any long-runner is still running for this service (unless --force, which cascade-kills targets first).

func (*Server) KillInfraContainer

KillInfraContainer stops one infra container by (stack, service, name) — leaves the rest of the service's infra (and any running targets) untouched. Used by the TUI to manage infra entries like any other tab.

func (*Server) KillTarget

KillTarget stops the named instance with the requested SIGTERM grace (defaults to 10s; 0 means immediate SIGKILL). Idempotent.

func (*Server) ListRuns

ListRuns returns the timestamps of archived runs for the target, newest first.

func (*Server) ListServices

ListServices returns every service in the requested stack. Request.Stack of "" → default stack; "*" → union across every registered stack (preserving stack name in each returned Service for disambiguation).

func (*Server) ListStacks

ListStacks returns every registered stack. Stacks are fixed at startup, so this reads them straight from state.

func (*Server) ListVolumes

ListVolumes returns one Volume row per compose-declared volume on the service, with size + backup count. Read-only.

func (*Server) Ping

Ping is the cheap handshake clients use to verify the daemon is alive. `core start` uses it to detect an already-running instance.

func (*Server) PrepareReinstall

PrepareReinstall writes a checkpoint listing every running go-exec target (with its env, for relaunch), fsyncs it, then signals the daemon to shut down. Containers are not included — they survive the daemon's death independently.

Concurrency: rejects a second PrepareReinstall if one is already pending (the checkpoint file's existence is the guard).

func (*Server) RestartInfraContainer

RestartInfraContainer restarts one infra container in place (podman restart — stop+start without recreating, preserves volume bindings).

func (*Server) RestartTarget

RestartTarget is Kill + Start in one RPC. Mutual-exclusion-safe: the kill completes before the start tries to take the slot.

func (*Server) RestoreVolume

RestoreVolume replaces each volume from the matching backup. Refuses while service is up.

func (*Server) Shutdown

Shutdown is the no-checkpoint daemon stop. With force=false it SIGTERMs every running go-exec target with a 10s grace each and leaves containers alone. With force=true it also calls KillInfra(force=true) on every service that has an active infra session — cascade-killing any remaining targets and tearing down infra containers.

Concurrency: just like PrepareReinstall, the shutdown signal is fired after the response is sent so the client gets a clean reply.

func (*Server) ShutdownCh

func (s *Server) ShutdownCh() <-chan struct{}

ShutdownCh returns a channel the daemon's main loop waits on. Closed when SignalShutdown is called (e.g., by PrepareReinstall after the checkpoint is durable).

func (*Server) SignalShutdown

func (s *Server) SignalShutdown()

SignalShutdown closes the shutdown channel. Idempotent.

func (*Server) StartInfra

StartInfra brings up a service's infrastructure containers and auto-runs every one-shot target whose successful completion the long-runners depend on. Idempotent.

func (*Server) StartTarget

StartTarget brings up the named target in the requested mode (defaults to go-exec), synthesizing the target's env before launch.

func (*Server) Status

Status reports everything `a-novel core status` needs in one round-trip.

func (*Server) StreamLogs

StreamLogs server-streams log lines for a target. Three modes:

  • default: snapshot of current.log from start to end (one shot)
  • --follow: snapshot + subscribe to new lines until proc terminates or client disconnects
  • --run-id: archived run (no follow regardless)

Order: archived/snapshot lines come first, in file order; new lines (when --follow) interleave after. Each emitted LogLine carries the original timestamp + stream tag.

func (*Server) Watch

Watch streams every phase transition the runner emits, filtered by the caller's (stack, service, target_id) tuple. An empty filter field means "match any value" — clients usually pass (stack, service, "") to watch one service or all three empty to watch everything.

The stream stays open until the client cancels its side (or the daemon shuts down — the runner's emit fanout simply stops). No snapshot is emitted up-front; callers that need the initial state should pair Watch with a `ListServices` snapshot themselves (the CLI's `ps --watch` pattern).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL