agent

package
v0.2.16 Latest Latest
Warning

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

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

Documentation

Overview

Package agent runs the long-poll loop on the runner host. In model B it owns the GitHub relationship: it polls GitHub with the customer's App key, reports its queue metadata to the keyless control plane, and — once the control plane picks a job — mints the JIT config itself and drives the Driver to provision.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ActionCache added in v0.2.12

type ActionCache interface {
	Fill(job domain.Job)
	Reclaim() error
}

ActionCache keeps the host's action archive cache. Fill must not block: it runs on the dispatch path.

type Agent

type Agent struct {
	Version       string
	FailedRequest string
	FailedVersion string
	UpdateError   string
	Update        func(context.Context, string, string) error
	Healthy       func(context.Context) error
	Name          string
	Labels        []string
	Driver        driver.Driver
	Client        *api.Client

	// MinFreeDisk is the free-space floor on the driver's image store, in bytes.
	// Under it the agent deselects itself — it keeps polling but reports no free
	// capacity, so the work stays schedulable on a host that can actually run it
	// instead of failing here. Zero disables the gate, as does a driver that
	// can't locate its store.
	MinFreeDisk uint64

	// ReclaimFloor is the free-space mark reclaim works to keep clear. It is
	// separate from MinFreeDisk so that disabling the gate leaves upkeep
	// running: an operator who never wants work refused still wants the caches
	// collected. Zero disables reclaim.
	ReclaimFloor uint64

	// Metrics receives the agent's series; served only when the operator sets
	// a metrics listen address.
	Metrics *metrics.Agent

	// Actions, when set, is filled from each finished job and emptied first
	// under disk pressure.
	Actions ActionCache

	// Source, when set, says when a pending job has left GitHub's queue: it
	// was not re-emitted by the last clean pass of its scope. A paused or
	// failing scope evicts nothing, so a job still waiting is never dropped.
	Source Freshness
	// contains filtered or unexported fields
}

Agent runs the dispatch loop and tracks busy slots.

func New

func New(name string, labels []string, drv driver.Driver, client *api.Client, minter Minter, orgPriority map[string]int, jobs <-chan domain.Job) *Agent

New constructs an Agent. minter mints JIT configs with the customer's App key; jobs is the stream of pending jobs from the GitHub source; orgPriority is the advisory per-org priority reported to the control plane.

func (*Agent) ReconcileOrphans

func (a *Agent) ReconcileOrphans(ctx context.Context) error

ReconcileOrphans destroys slots the Driver still owns that this agent isn't accounting for: what a previous process lifetime left behind (launchd SIGKILL/OOM), and what a Destroy that failed mid-dispatch stranded. Called at startup before Run, and on reconcileInterval thereafter.

The listing is read before the busy set, and never the other way around: a slot that goes busy in between was created after the listing, so it can't be in it. Reversing that would let a runner provisioned mid-sweep look like an orphan and be destroyed under its job.

Driver.List filters by NamePrefix, so unrelated user VMs are safe. Running two ushr-agent instances on the same host with the default prefix would reap each other's VMs — single-agent assumption holds for v0.1.

func (*Agent) Run

func (a *Agent) Run(ctx context.Context) error

Run blocks until ctx is cancelled, then waits for in-flight dispatches to clean up before returning.

type DispatchObserver

type DispatchObserver interface {
	DispatchDone(handle string, failed bool)
}

DispatchObserver is implemented by sources that keep a per-dispatch supply ledger (scale sets): every terminal report clears the runner's entry immediately, so supply reconciliation runs on real events rather than TTL backstops. Handles the source never minted are a no-op.

type Freshness added in v0.2.13

type Freshness interface {
	// RelistGap bounds how stale an emitted job's state can be.
	RelistGap() time.Duration
}

Freshness is implemented by a source that re-emits every job still queued on each clean pass and ends the pass with a marker (domain.Job.PassStart): the GitHub poller. Without it the agent can only age jobs out by queueTTL.

type Minter

type Minter interface {
	Mint(ctx context.Context, name string, job domain.Job, labels []string) (string, error)
}

Minter mints a single-use JIT runner config with the customer's own App key. *jit.Minter is the production implementation; the scaleset Source is the other (it registers the runner into its scale set at mint time).

Jump to

Keyboard shortcuts

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