runnerspool

package
v0.9.0 Latest Latest
Warning

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

Go to latest
Published: Oct 14, 2026 License: Apache-2.0 Imports: 18 Imported by: 0

Documentation

Overview

Package runnerspool stores proxy decisions until the authenticated runner stream acknowledges their durable org ingestion. The proxy and daemon use the same private directory, serialized by a process-shared file lock.

Index

Constants

View Source
const (
	// ReplayBatch bounds the uncommitted local ACK window retained by org receipts.
	ReplayBatch = 64
	MaxRecords  = 50000
	MaxBytes    = 32 << 20
	// MaxRecordBytes leaves the record envelope below the wire control bound.
	MaxRecordBytes = (1 << 20) - 4096
)

Variables

View Source
var ErrFull = errors.New("runner decision spool is full")
View Source
var ErrSealed = errors.New("runner spool is durably sealed")

ErrSealed refuses new evidence production after exact settled retirement.

Functions

This section is empty.

Types

type Record

type Record struct {
	SpoolID  uuid.UUID          `json:"spool_id"`
	Seq      int64              `json:"seq"`
	Hash     string             `json:"hash"`
	Decision egress.DecisionLog `json:"decision"`
	Count    uint64             `json:"count,omitempty"`
	DropEnd  uint64             `json:"drop_end,omitempty"`
}

Record is one stable, replayable decision. Seq zero is an overflow summary, whose durable identity is its hash; ordinary records have positive sequences.

func (Record) Marshal

func (r Record) Marshal() ([]byte, error)

Marshal is the bounded EVENT.spool payload; no run token authenticates replay.

func (Record) Position

func (r Record) Position() ackcursor.Pos

Position is the acknowledgement cursor's sequence and content identity.

func (Record) ValidHash

func (r Record) ValidHash() bool

ValidHash refuses modified or cross-stream rows before durable ingestion.

type Spool

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

Spool is safe across goroutines and independently opened proxy/daemon handles.

func Open

func Open(dir string, runID uuid.UUID) (*Spool, error)

Open refuses unsafe or corrupt existing state. A missing directory starts a new private stream; an existing stream never silently resets its cursor.

func (*Spool) AckOverflow

func (s *Spool) AckOverflow(ctx context.Context, row Record) error

AckOverflow records only the frozen interval, retaining later refusals.

func (*Spool) After

func (s *Spool) After(ctx context.Context, seq int64, limit int) (rows []Record, err error)

After implements ackcursor.Source. The acknowledged row's identity lives in the manifest, so reclaimed payloads do not make ackcursor infer a reset.

func (*Spool) Append

func (s *Spool) Append(ctx context.Context, decision egress.DecisionLog) error

Append commits before returning. An unreserved producer must refuse on any error; the proxy separately reserves capacity before forwarding requests.

func (*Spool) AppendAdmitted

func (s *Spool) AppendAdmitted(ctx context.Context, decision egress.DecisionLog) error

AppendAdmitted finishes a request whose proxy already reserved capacity. Overflow refuses new requests, never discards this previously admitted tail.

func (*Spool) CanRecord

func (s *Spool) CanRecord(ctx context.Context) error

CanRecord checks durable overflow state. Concurrent producers must also reserve capacity; checking alone cannot guarantee space for a later append.

func (*Spool) Close

func (s *Spool) Close() error

Close releases this process's handles; it never deletes pending decisions.

func (*Spool) Get

func (s *Spool) Get(ctx context.Context) (pos ackcursor.Pos, err error)

Get implements ackcursor.Store.

func (*Spool) Overflow

func (s *Spool) Overflow(ctx context.Context) (row *Record, err error)

Overflow freezes one cumulative refused-attempt interval before transmission. A crash or new refusals cannot change the identity/count of an in-flight row.

func (*Spool) Receipt

func (s *Spool) Receipt(ctx context.Context) (out types.RunnerSpoolReceipt, err error)

Receipt reads durable acceptance, not the unacknowledged current head.

func (*Spool) Refuse

func (s *Spool) Refuse(ctx context.Context) error

Refuse durably counts one egress admission refused because capacity is full.

func (*Spool) Replay

func (s *Spool) Replay(ctx context.Context, send func(context.Context, []Record) error) error

Replay uses the shared acknowledgement cursor. send gets each batch in seq order and must return nil only after durable checked org ingestion of every row in it (H2 Peer.EventsAck), not after a write.

Replay ends once it has delivered the head (rows and refused attempts) seen when it started. Rows a live proxy appends meanwhile wait for the next call, so a producer faster than the drain cannot keep Replay running.

func (*Spool) Seal

func (s *Spool) Seal(ctx context.Context, expected types.RunnerSpoolReceipt) (sealed bool, err error)

Seal requires the proxy's lifetime writer lock and an exact fully accepted current head. A still-running producer or unsettled evidence defers sealing.

func (*Spool) Set

func (s *Spool) Set(ctx context.Context, pos ackcursor.Pos) error

Set commits an acknowledged cursor before reclaiming any payload. A crash during reclamation leaves harmless acknowledged files, never missing history.

func (*Spool) Stats

func (s *Spool) Stats(ctx context.Context) (depth int, bytes int64, drops uint64, err error)

Stats reports unacknowledged decisions and the total refused-overflow count.

Jump to

Keyboard shortcuts

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