output

package
v0.9.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 25, 2026 License: Apache-2.0 Imports: 11 Imported by: 0

Documentation

Index

Constants

View Source
const (
	DirectionClientToHost = byte(1)
	DirectionHostToClient = byte(2)

	KindInput  = byte(1)
	KindOutput = byte(2)

	MaxHeader  = 16 * 1024
	MaxPayload = 8 * 1024 * 1024
)

Variables

View Source
var (
	BinaryMagic = []byte{0x44, 0x45, 0x4E, 0x42}
	Version     = byte(1)
)

Binary envelope wire format. This is intentionally the same DENB envelope used by the Swift transport: magic "DENB", version 1, direction byte, kind byte, header length (u32 BE), payload length (u32 BE), JSON header, payload.

Functions

func EncodeInput

func EncodeInput(metadata InputMetadata, payload []byte) ([]byte, error)

func EncodeOutput

func EncodeOutput(sessionID string, epoch, sequence uint64, payload []byte) ([]byte, error)

func SplitPayload

func SplitPayload(payload []byte) [][]byte

SplitPayload splits one logical payload into MaxPayload-sized chunks so a large spool read or capture snapshot can be sequenced into valid frames.

Types

type Anchor

type Anchor struct {
	Epoch    uint64 `json:"epoch"`
	Sequence uint64 `json:"sequence"`
}

Anchor identifies the next byte a client needs within one epoch.

type DecodedFrame

type DecodedFrame struct {
	SessionID string
	Epoch     uint64
	Sequence  uint64
	Payload   []byte
}

func DecodeOutput

func DecodeOutput(data []byte) (DecodedFrame, error)

DecodeOutput parses one Host-to-Client output envelope. The returned payload is a copy, so the input buffer can be reused.

type Frame

type Frame struct {
	SessionID string
	Epoch     uint64
	Sequence  uint64
	Payload   []byte
}

Frame is one sequenced PTY output chunk. PayloadLength is derived from the payload; the wire codec keeps it explicit in the header.

func (Frame) Anchor

func (f Frame) Anchor() Anchor

Anchor returns the next byte position after this frame.

type InputMetadata

type InputMetadata struct {
	Version       string
	SessionID     string
	AttachmentID  string
	PayloadLength int
	Sequence      uint64
}

func DecodeInput

func DecodeInput(data []byte) (InputMetadata, []byte, error)

type Plan

type Plan int

Plan is the recovery strategy for a reconnecting client.

const (
	PlanExact    Plan = iota // anchor equals the ring upper bound
	PlanTail                 // anchor is inside the retained interval
	PlanReanchor             // no anchor, wrong epoch, or anchor evicted
)

type Recovery

type Recovery struct {
	Plan     Plan
	Epoch    uint64
	Lower    uint64
	Upper    uint64
	Frames   []Frame
	Reanchor bool
}

Recovery is the bounded reply Host sends on attach.

func (Recovery) Anchor

func (r Recovery) Anchor() Anchor

type Ring

type Ring struct {
	Capacity int
	MaxBytes int
	Epoch    uint64
	// contains filtered or unexported fields
}

Ring is a bounded sequence interval retained by Host for reconnecting clients. Sequence values are byte positions since the epoch start, matching the spool byte stream and the Swift Host OutputRing semantics.

func NewRing

func NewRing(epoch uint64, capacity, maxBytes int, nextSequence uint64) *Ring

func (*Ring) Anchor

func (r *Ring) Anchor() Anchor

func (*Ring) Append

func (r *Ring) Append(sessionID string, payload []byte) (Frame, error)

Append records one frame, evicting the oldest frames to keep both the frame count and the retained byte total bounded.

func (*Ring) Frames

func (r *Ring) Frames() []Frame

func (*Ring) Lower

func (r *Ring) Lower() uint64

func (*Ring) Plan

func (r *Ring) Plan(anchor *Anchor) Plan

func (*Ring) Recovery

func (r *Ring) Recovery(anchor *Anchor) Recovery

Recovery returns the frames needed by a client. For a tail the first frame is trimmed so its header starts exactly at the requested byte; for reanchor the entire retained interval is returned and callers decide whether to send a tmux screen snapshot instead.

func (*Ring) Reset

func (r *Ring) Reset(epoch, nextSequence uint64)

func (*Ring) Upper

func (r *Ring) Upper() uint64

type SpoolWatcher added in v0.9.0

type SpoolWatcher struct {
	// contains filtered or unexported fields
}

SpoolWatcher tails an append-only spool from a persisted byte offset. Its polling interval can change while it is running so callers can reserve fast output delivery for the terminal the user is actively viewing.

func NewSpoolWatcher added in v0.9.0

func NewSpoolWatcher(path string, offset int64, onBytes func([]byte), onRotate func(), onOverflow func()) (*SpoolWatcher, error)

NewSpoolWatcher returns a watcher positioned at offset in path. Callbacks may be nil. Start begins polling.

func (*SpoolWatcher) Close added in v0.9.0

func (w *SpoolWatcher) Close()

Close stops the watcher and releases its file descriptor. It is safe to call multiple times.

func (*SpoolWatcher) Drain added in v0.9.0

func (w *SpoolWatcher) Drain()

Drain synchronously tails any output currently available. It is used at an attach boundary so a background cadence cannot delay the newly visible terminal.

func (*SpoolWatcher) Interval added in v0.9.0

func (w *SpoolWatcher) Interval() time.Duration

Interval returns the current polling cadence.

func (*SpoolWatcher) Offset added in v0.9.0

func (w *SpoolWatcher) Offset() int64

Offset returns the next byte position the watcher will deliver.

func (*SpoolWatcher) Pause added in v0.9.0

func (w *SpoolWatcher) Pause()

Pause blocks until any in-flight drain finishes, then prevents new drains. Use it while preparing a checkpoint replay so live reads cannot interleave.

func (*SpoolWatcher) Ping added in v0.9.0

func (w *SpoolWatcher) Ping()

Ping asks the watcher to check for output without waiting for its next poll.

func (*SpoolWatcher) Resume added in v0.9.0

func (w *SpoolWatcher) Resume()

Resume re-enables draining after Pause and asks the watcher to check immediately.

func (*SpoolWatcher) SetInterval added in v0.9.0

func (w *SpoolWatcher) SetInterval(interval time.Duration)

SetInterval changes the polling cadence and wakes the loop so a shorter interval takes effect immediately. Invalid durations leave the cadence unchanged.

func (*SpoolWatcher) SetMaxBytes added in v0.9.0

func (w *SpoolWatcher) SetMaxBytes(maxBytes int64)

SetMaxBytes configures the spool size cap. When the watcher passes the cap it calls onOverflow so the owner can compact the spool.

func (*SpoolWatcher) SkipTo added in v0.9.0

func (w *SpoolWatcher) SkipTo(offset int64) error

SkipTo re-bases the watcher to a byte position covered by a snapshot. It must be called while paused and the offset must be within the current file; any unread bytes below the target were already rendered by the snapshot and must not be delivered again.

func (*SpoolWatcher) Start added in v0.9.0

func (w *SpoolWatcher) Start()

Start begins watching. Repeated calls are safe and have no effect.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL