docs-internal/engine/GUARD.md
The retry mechanism enables optimistic routing with cache invalidation:
This approach optimizes for the common case (actors are running and routes are valid) while gracefully handling the uncommon case (actors have moved/stopped) without sacrificing performance
Initial Request (Attempt 1):
Retry Attempts (Attempts 2-N):
502 Bad Gateway to clientConfiguration:
503 Service Unavailable with x-rivet-error headerServices that want to trigger guard retries must respond with:
503 Service Unavailable status codex-rivet-error: <error> headerRequests are routed in the following priority order:
x-rivet-target)When the x-rivet-target header is present, routes to specific service types:
Actor Services (x-rivet-target: actor):
x-rivet-actor: <actor_id> - UUID of the specific actor instancex-rivet-addr: <address> - Direct address override for actor locationRunner (x-rivet-target: runner):
pegboard.lan_host:pegboard.port)When no x-rivet-target header is present:
api_public.lan_host:api_public.port)Returns 404 Not Found if no routing rules match.
The Gateway (a portion of Guard) acts as a proxy for HTTP requests and WebSocket connections to actors.
In addition to header-based routing, Guard can route requests to actors when the request path matches:
/gateway/{actor_id}/{...path}/gateway/{actor_id}@{token}/{...path}When connecting a WebSocket, Guard may also determine the actor target from Sec-Websocket-Protocol when it consists of comma delimited dot separated pairs like rivet_target.actor,rivet_actor.{actor_id}.
The Gateway allows us to implement hibernatable WebSockets (see HIBERNATING_WS.md) for actors. We can keep a client's WebSocket connection open while simultaneously allowing for actors to sleep, resulting in 0 usage when there is no traffic over the WebSocket. The actor is automatically awoken when a WebSocket message is transmitted to the Gateway.