3.8 KiB
Grid-session supervision
Live integrated and split modes run through SessionSupervisor. Its injected
GridSessionBackend makes the lifecycle deterministic under a fake grid while
the live-grid adapter reuses libremetaverse::NetworkManager for native
login, event-queue readiness, disconnect callbacks, and logout.
The native login does not yield a session until the login response has populated
the existing inventory skeleton and a current simulator/UDP circuit exists.
The adapter then waits for that simulator's event queue before publishing full
readiness. Existing GridClient inventory/world managers and its single
movement-update owner remain the composition owners; the adapter never creates
duplicates. Only its generation-scoped readiness/disconnect subscriptions are
recreated, and their RAII guards are dropped before logout.
States and reasons
| State | Transport connected | Agent ready | Exit condition |
|---|---|---|---|
stopped |
no | no | startup, resume, or force reconnect |
connecting |
no | no | login result, operator control, or cancellation |
degraded |
yes | no | readiness, disconnect, or operator control |
online |
yes | yes | readiness loss, disconnect, or operator control |
backoff |
no | no | cancellation-driven timer or operator control |
authentication-blocked |
no | no | resume/force reconnect or shutdown |
paused |
no | no | resume/force reconnect, logout, or shutdown |
shutting-down |
no | no | session logout, audit flush, and joined owner task |
Every transition carries a stable SessionReason; raw login responses, server
messages, credentials, capability URLs, and session tokens cannot enter the
failure or observation types. SessionStatus reports transport connectivity
and complete readiness separately.
Invalid credentials and invalid local login configuration stop automatic
retry. Transport failures, maintenance, kicks, simulator disconnects, and
server failures retry with exponential backoff. reconnect.maximum_delay_seconds
is a hard cap. A server retry hint is a minimum up to that cap. Per-instance
jitter is bounded by jitter_basis_points, preventing synchronized reconnects,
and a connection that remains up for stable_reset_seconds resets the failure
streak.
Backoff defaults are one second initially, 60 seconds maximum, 20 percent
jitter, and a 120-second stable reset window. All waits use Tokio timers inside
select! with cancellation/control; there are no blocking sleeps.
Generation and work safety
Each attempt receives a monotonically changing generation and cancellation
token. Session-scoped subscriptions, readiness ownership, and workers belong to
the returned GridSession and are closed once by its consuming logout method.
Late inference/tool results are accepted only when accepts_result sees their
exact generation in fully ready state.
While not ready, bounded read-only work may queue. Mutation work—including nominally idempotent mutation—is rejected, because the supervisor cannot prove that a previous policy authorization remains valid. Work IDs are deduplicated across reconnects with a bounded recent-ID set, so reconnect never silently duplicates an outbound response. Queued reads are released once into the new generation.
Shutdown
Shutdown first rejects new work and invalidates the generation token, which
cancels inference, tools, and scheduled consumers sharing it. It then consumes
the active session for one logout attempt, waits within
timeouts.shutdown_seconds, calls the backend's bounded audit-flush hook, and
joins the supervisor owner task. A late task is aborted and awaited by the
handle, so no task or socket is detached.
Focused deterministic verification:
cargo test --locked -p metacrate-grid-agent --lib session_tests
cargo clippy --locked -p metacrate-grid-agent --all-targets -- -D warnings