agent

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Aug 18, 2026 License: AGPL-3.0 Imports: 23 Imported by: 0

Documentation

Overview

Package agent runs one host's share of a distributed load test.

An agent is a supervisor, not a load generator. It joins the coordinator, spawns worker processes on its host, subdivides the quota it was given across them, and relays their telemetry upward. Keeping supervision out of the processes that generate load is what allows a worker to be killed, crash, or be starved of CPU without taking the host's participation in the run down with it.

Index

Constants

View Source
const (
	// DefaultVUsPerCore is the advertised capacity per core. Virtual users
	// are goroutines blocked on network I/O for most of their lives, so a
	// core carries far more of them than it could carry busy threads.
	DefaultVUsPerCore = 1000
)

Defaults for a zero Config.

Variables

This section is empty.

Functions

This section is empty.

Types

type Agent

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

Agent supervises one host's worker processes.

func New

func New(cfg Config) (*Agent, error)

New prepares an agent. It neither listens nor connects; Run does both.

func (*Agent) OnAccepted

func (a *Agent) OnAccepted(_ context.Context, msg *loadwavev1.Accepted) error

OnAccepted implements control.Handler.

func (*Agent) OnHeartbeat

func (a *Agent) OnHeartbeat(session *control.Session, beat *loadwavev1.NodeHeartbeat)

OnHeartbeat implements control.SessionHandler.

Each worker's VU count is kept separately and summed, rather than accumulated into a running total. A worker that dies between heartbeats simply stops contributing at the next recount, where an incremental total would keep its VUs on the books forever.

func (*Agent) OnJoin

func (a *Agent) OnJoin(_ context.Context, session *control.Session) error

OnJoin implements control.SessionHandler.

func (*Agent) OnLeave

func (a *Agent) OnLeave(session *control.Session)

OnLeave implements control.SessionHandler.

func (*Agent) OnLog

func (a *Agent) OnLog(_ *control.Session, event *loadwavev1.LogEvent)

OnLog implements control.SessionHandler.

func (*Agent) OnMetrics

func (a *Agent) OnMetrics(_ *control.Session, batch *loadwavev1.MetricBatch)

OnMetrics implements control.SessionHandler.

Batches are relayed to the coordinator unchanged, still carrying the worker's own node id. Merging them here would save a little bandwidth but would cost the operator the ability to see which process in a fleet is misbehaving, which is exactly the question a distributed run raises.

func (*Agent) OnRunStatus

func (a *Agent) OnRunStatus(session *control.Session, update *loadwavev1.RunStatusUpdate)

OnRunStatus implements control.SessionHandler.

Worker phases are folded into a single agent-level phase rather than relayed one by one. The coordinator decides a run is over when every participating agent reports a terminal phase, and forwarding each worker's status verbatim would have the agent's phase flapping between its workers' — so a run with one worker still going could look finished.

func (*Agent) OnSetQuota

func (a *Agent) OnSetQuota(_ context.Context, msg *loadwavev1.SetQuota) error

OnSetQuota implements control.Handler.

func (*Agent) OnStartRun

func (a *Agent) OnStartRun(_ context.Context, msg *loadwavev1.StartRun) error

OnStartRun implements control.Handler.

func (*Agent) OnStopRun

func (a *Agent) OnStopRun(_ context.Context, msg *loadwavev1.StopRun) error

OnStopRun implements control.Handler.

Stopping waits for workers to wind down, which takes as long as the plan's grace period allows. That cannot happen on the control stream's receive goroutine: blocking there would stop the agent noticing anything else the coordinator says, including a follow-up hard stop.

func (*Agent) Run

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

Run serves workers and stays joined to the coordinator until ctx is cancelled.

func (*Agent) SocketPath

func (a *Agent) SocketPath() string

SocketPath returns the worker control socket's filesystem path.

type Config

type Config struct {
	// NodeID identifies this agent to the coordinator. Reconnecting with the
	// same id is what lets the coordinator recognise a returning agent rather
	// than counting it twice.
	NodeID string

	// CoordinatorTarget is the coordinator's gRPC address.
	CoordinatorTarget string

	// Workers is how many worker processes to spawn per run. Zero derives it
	// from the core count.
	Workers int

	// MaxVUs is the ceiling this agent advertises. Zero derives one from the
	// core count.
	MaxVUs int

	// Labels are advertised to the coordinator, for operator-facing grouping.
	Labels map[string]string

	// SocketPath is where the worker control socket lives. Zero picks a path
	// under the system temporary directory.
	SocketPath string

	// WorkerArgs are appended to every spawned worker's command line.
	WorkerArgs []string

	// Executable is the binary to spawn as a worker. Empty uses this process's
	// own path, which is almost always right: a Go SDK test compiles its
	// scenarios into the same binary that runs the agent.
	Executable string

	Logger *slog.Logger
}

Config describes an agent.

Jump to

Keyboard shortcuts

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