Documentation
¶
Overview ¶
Package attachplane is the dial-back half of Rainier's terminal attach: the pairing table, the runner's dial-back endpoint, and the splice that joins one client stream to one runner socket.
It exists because a control plane never dials into a runner (spec rule 3). A client's socket arrives at the host, the plane parks it under a fresh attach id and asks the session's runner — through the host — to dial back carrying that id; the dial-back claims the parked socket and the two are spliced until either end stops. Everything above the plane (who may attach, in which mode, and whether the session is attachable at all) is the application's, and everything below it is the host's sockets.
A Host supplies the three things a plane cannot know: how to authenticate a runner's dial-back, how to reach a runner with a command, and this replica's own dial-back URL. The state is deliberately replica-local: the dial-back's target_url names the exact replica holding the client socket, so no other one can be asked to claim a pairing, and a replica dying takes only its own live attaches with it — clients re-attach, nothing else is lost. A host fronted by a gateway names the gateway's public URL instead and routes the dial-back back to this replica itself.
The plane interprets no terminal traffic: a message is decoded to be forwarded and for no other reason, and no message, no byte of one, and no length of one is ever logged.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ClientStream ¶
func ClientStream(c *websocket.Conn) control.TerminalStream
ClientStream wraps an accepted client websocket as the control.TerminalStream the application (and this plane's broker) speaks. It also sets the socket's read limit: a snapshot replaying a large scrollback is the biggest frame either direction of the splice ever carries, and the plane owns that policy for both halves of it.
The caller keeps the socket's own lifetime — a handler that accepted it still defers its CloseNow — and hands the reason it ends with to Close.
Types ¶
type Host ¶
type Host interface {
// IdentifyRunner authenticates a runner's dial-back and names the pool
// and runner it is. Any error refuses the dial-back before the socket is
// upgraded and before any pairing is claimed.
IdentifyRunner(ctx context.Context, r *http.Request) (control.PoolID, control.RunnerID, error)
// Send delivers a command to a runner — the dial_attach, in this plane's
// case — reporting only whether it was queued for delivery.
Send(pool control.PoolID, id control.RunnerID, m runner.ToRunner) error
// BackURL is this replica's attach-back WebSocket URL for an attach id.
// It must carry the id as the `attach_id` query parameter, which is what
// BackHandler reads it back out of, and it must route to THIS replica: a
// host with a gateway in front of it names the gateway's public URL and
// routes the dial-back home itself.
BackURL(attachID string) string
}
Host is what a plane needs from its host: the three things it cannot know on its own. Every method is one dependency.
type Options ¶
type Options struct {
// PairTTL bounds how long a parked client socket waits for its runner's
// dial-back before the plane closes it. Zero means 15s.
PairTTL time.Duration
// Logf receives the plane's operational log lines — a refused pairing, a
// dial-back that never came. It never receives a terminal message, a byte
// of one, or a length of one. Zero means log.Printf.
Logf func(string, ...any)
}
Options configures a plane. The zero value is usable: the pairing TTL defaults and log lines go to the standard logger.
type Plane ¶
type Plane struct {
// contains filtered or unexported fields
}
Plane is one replica's attach plane: the pairings it is waiting on, the dial-back endpoint they are claimed through, and the broker that mints them. Its zero value is not usable — construct it with New.
func New ¶
New returns a plane over h. It panics on a nil host: a plane without one cannot reach a single runner, and failing at composition is better than failing at the first attach.
func (*Plane) BackHandler ¶
BackHandler returns the runner's dial-back endpoint. Mount it at the path BackURL names.
func (*Plane) Broker ¶
func (p *Plane) Broker() control.AttachmentBroker
Broker returns the plane behind control.AttachmentBroker, for the application's attachment service to hand authorized streams to.