Request Lifecycle
An Andurel v2 application is one codebase with multiple process graphs. Understanding which process owns a request (or a job) keeps composition roots honest.
Web process (cmd/app)
Typical path for an HTTP request:
1.env / process env
2 |
3 v
4config.LoadEnvironment()
5 |
6 v
7Fx build: config, storage.Connection, models,
8 services, controllers, cookies.Jar, router
9 |
10 v
11pkg/server starts Echo (config.HTTP timeouts)
12 |
13 v
14middleware: kiks bag -> CSRF -> auth -> Inertia (when set)
15 |
16 v
17controller (injected collaborators)
18 |
19 +---> inertia.Renderer Page / Redirect / Location
20 |
21 +---> hypermedia Templ / Datastar
22 |
23 v
24kiks persist dirty cookies + flashes
25 |
26 v
27response; on signal: graceful shutdown, close pool
config.LoadEnvironment()loads.envand process environment before Fx.- Fx constructs validated config providers,
storage.Postgresasstorage.Connection, models, services, controllers,cookies.NewJar, and the router. pkg/serverstarts Echo with HTTP timeouts fromconfig.HTTP.- Middleware runs in order: kiks bag load (
jar.EchoMiddleware), CSRF, auth gates, Inertia middleware when configured. - A controller handler receives injected collaborators (not ambient globals).
- The handler validates input, calls model APIs, and either renders Inertia via
*inertia.Renderer(Page/ redirects) or returns Templ / Datastar throughpkg/hypermedia. - kiks persists dirty bagged cookies and flashes before the response commits.
- On signal, Fx stops the server with a graceful shutdown timeout and closes the pool.
Queue insertion belongs here: inject storage.InsertQueue (or *storage.QueueInsert) and call Insert / InsertTx after domain writes. Do not start River workers in the web process.
Queue process (cmd/queue)
cmd/queue constructs the same storage.Connection, a River QueueProcessor, registered workers, telemetry, and email transports. It does not construct Echo or Inertia.
1Fx build: storage.Connection, QueueProcessor,
2 workers, telemetry, email senders
3 |
4 v
5processor starts on shared pgx pool (riverpgxv5)
6 |
7 v
8job.Work(ctx, ...) with injected models / email
9 |
10 v
11soft-stop from config.NewQueueWorker
12 |
13 v
14shutdown: stop processor, close pool
- Fx starts the processor against the shared pgx pool (
riverpgxv5). - Workers run job
Workmethods with injected model and email collaborators. - Soft-stop and lifecycle config come from
config.NewQueueWorker. - Shutdown stops the processor, then closes the pool.
Commit domain state and a River job together with storage.RunInTransaction and InsertTx in the web process so workers never see half-written rows. See Queues.
SSR process (cmd/ssr)
Inertia SSR is optional and per-page.
1cmd/app Page(...).SSR()
2 |
3 +-- development --> Vite /__inertia_ssr
4 |
5 +-- otherwise ----> INERTIA_SSR_URL
6 |
7 v
8 cmd/ssr (Node bind
9 on INERTIA_SSR_LISTEN)
10 |
11 v
12 HTML fragment back to
13 renderer; client fallback
14 unless fail-fast
cmd/ssr owns the Node runtime bind (INERTIA_SSR_LISTEN). The web renderer posts to INERTIA_SSR_URL (or Vite's /__inertia_ssr in development). Pages still opt into SSR individually. See SSR.
Where state lives
| Concern | Owner |
|---|---|
| PostgreSQL rows | storage.Connection / storage.Transaction in the owning process |
| Session and flash | kiks cookies on the HTTP path (Cookies & Sessions) |
| Background side effects | River jobs processed in cmd/queue |
| Browser document / visits | Inertia renderer in cmd/app, optional Node SSR in cmd/ssr |