Expand description
Daemon client lifecycle with typed provenance (PK06-4, K06 “Host composition”).
Two supported lifecycles for a service host that outlives one window of one app:
Provenance::Owned: this process launched the host (through theLauncherthe app supplied), recorded the launched process’sAdoptedIdentity(pid plus start time), and waited for that same pid to publish itself. Only an owned host may be stopped by this lifecycle (DaemonLifecycle::shutdown_owned), and only while the recorded identity still names the launched process. A replacement the lifecycle launches itself is owned too.Provenance::Attached: some other process started the host (another shell of the same app, a CLI, an installer). The lifecycle verifies the endpoint’s identity and generation and uses it; it never signals it, never stops it and never infers a right to. An arbitrary discovered pid is never owned.DaemonLifecycle::release_sessionon an attached client closes that client’s connection and nothing else.
The pieces, in the order the spec names them:
DaemonLifecycle::attach_or_launch: discover the live host. A live, reachable host whose process generation still matches is attached (after the identity check below). Otherwise, when aLauncherwas given, take the cross-process spawn claim, launch, and wait for the launched pid to publish. Without a launcher, no host isLifecycleError::NoHost.DaemonLifecycle::acquire_session: revalidates the host (record, process generation, and the connection’s own identity check) before it hands out aSession. A host that exited is relaunched only when this lifecycle owns the launcher and the restart budget (RestartPolicy, the same tracker the private-child supervisor uses) allows it; a spent budget isLifecycleError::RestartExhausteduntilreset_restart_budget.Session::call: revalidates before the request is written and again before the reply is handed back. A reply that arrives after the host changed generation is not delivered (LifecycleError::StaleGeneration): whether the request ran on the old host is unknown, so it is never replayed automatically.GenerationFenceis the same rule for transports that multiplex requests.DaemonLifecycle::release_session: ends one session. Never signals the host.DaemonLifecycle::shutdown_owned: owned hosts only. The app’s own graceful request first (when one was configured), the grace period, then the launched process tree is killed if it is still there.LifecycleError::NotOwnedfor an attached host, with nothing sent and nothing signalled.
Identity. The local backend (LocalBackend) connects with
Client::connect_expecting: the OS names the process on the listening end of the socket and
its executable must be the HostExpectation’s, before any byte is written. The kernel pid
must also equal the pid service.json names, and the record read during the handshake must be
the generation that was discovered (HostGeneration: endpoint, pid, process start time and
publication time). A host that fails any of it is LifecycleError::HostIdentity or a
retryable change error, and is never attached.
Not replaced. supervise_adopted stays the way to
run a private child (PrivateChild, secret on stdin). This module is for resident services
published through service.json.
Dropping a DaemonLifecycle that owns a host drops its OwnedChild, which ends the
launched process tree (the OwnedChild drop rule). Dropping an attached lifecycle ends nothing.
Structs§
- Daemon
Lifecycle - A client’s handle on a resident service host, with typed
Provenance. - Generation
Fence - Binds requests to a host generation. The epoch advances every time the host the lifecycle is
bound to changes (first bind, replacement, exit). A
Ticketissued under an older epoch can never complete: its reply isStale, so a late reply from a previous host cannot answer a request made to the next one. - Host
Generation - One incarnation of a published host: the facts in
service.jsonthat change when the host is replaced. Two values are the same generation only when every field is equal. - Lifecycle
Config - Timeouts, restart budget and the graceful stop request.
- Local
Backend - The local
service.jsontransport: discovery through the suite, identity throughClient::connect_expecting. - Release
Report - What
DaemonLifecycle::release_sessiondid. The host was not touched. - Session
- One client’s verified connection to the host, bound to the generation it was acquired
against. Dropping it releases it like
DaemonLifecycle::release_session. - Shutdown
Report - What
DaemonLifecycle::shutdown_owneddid. - Stale
- A request was issued under, or a reply tagged with, an epoch that is no longer current.
- Ticket
- A request in flight, bound to the epoch it was issued under.
Enums§
- Lifecycle
Error - Why a lifecycle operation failed.
- Provenance
- Who started the host this client uses, and so what the client may do to it.
- Spawn
Permit - Whether this process may start a host now.
Constants§
- ERROR_
LAUNCH_ FAILED - The host could not be launched or never published itself.
- ERROR_
NOT_ OWNED - The host is attached, not owned: this lifecycle may not stop it.
- ERROR_
RESTART_ EXHAUSTED - The owned host exited and the restart budget is spent.
- ERROR_
SESSION_ RELEASED - The session or the lifecycle was already released or shut down.
- ERROR_
STALE_ GENERATION - A reply (or a request) belongs to a host generation that is no longer the current one. Not retryable: the request may have run on the old host.
Traits§
- Host
Backend - How a lifecycle finds, verifies and reaches a host.
LocalBackendis theservice.jsontransport; tests and other transports implement it too. - Host
Link - A connection to exactly one host generation, as the lifecycle uses it.
Type Aliases§
- Graceful
Stop - The app’s own polite stop request (for example its
shutdownmethod), sent over a freshly verified connection to the owned host before any signal. AnErris not a failure of the shutdown: a host that exits as it answers often drops the connection. - Launcher
- Starts the host. Called with the cross-process claim held, at most once per start. The child it returns is owned by the lifecycle from then on; the app configures the command, including how it detaches.