Documentation
¶
Overview ¶
Package engine executes a load profile inside one worker process.
It owns the virtual user pool: starting goroutines as the profile ramps up, stopping them as it ramps down, and driving each one through its scenario in a loop. Everything above it — agents, the coordinator, the dashboard — deals in quotas and aggregates; this is the only layer that runs user code.
Index ¶
Constants ¶
const DefaultGracefulStop = 30 * time.Second
DefaultGracefulStop is how long in-flight iterations get to finish when a run ends, if the plan does not say.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct {
RunID string
NodeID string
Plan *loadwavev1.TestPlan
Registry *loadwave.Registry
Recorder *metrics.Recorder
HTTP *loadwave.HTTPClientFactory
Logger *slog.Logger
// StartAt is the instant, agreed across the whole fleet, that elapsed
// time is measured from. The engine idles until it arrives, so that nodes
// which received their orders at different moments still ramp together.
StartAt time.Time
// VUQuota is this node's virtual user count at the profile's peak.
VUQuota int
// IterationRateQuota caps iterations started per second on this node.
// Zero means unlimited.
IterationRateQuota int
// IterationQuota stops this node after this many completed iterations.
// Zero means unbounded.
IterationQuota uint64
// VUIDBase is the first virtual user id this node may allocate.
VUIDBase int64
// Shard identifies this node's slice of shared fixtures.
Shard loadwave.Shard
}
Config is everything the engine needs to execute one node's share of a run.
type Engine ¶
type Engine struct {
// contains filtered or unexported fields
}
Engine runs one node's share of a load profile.
func New ¶
New validates the configuration and prepares the engine. It starts nothing; Run does that.
func (*Engine) Iterations ¶
Iterations reports how many iterations have completed on this node.
func (*Engine) Run ¶
Run executes the profile and returns when the run has finished and every virtual user has stopped.
It returns nil for a run that completed or was stopped on request, and an error only when the run could not be carried out — a scenario's Setup failing, say. A load test full of HTTP 500s is a successful run with a bad result, and the distinction matters to anything scripting this.
func (*Engine) SetQuota ¶
SetQuota rescales this node's share while the run is in progress, either because an operator changed the target or because the fleet changed size.
A non-zero ramp introduces the change gradually rather than in one tick. The executor is mutated rather than replaced, so a change arriving mid-ramp eases from wherever the quota actually is instead of snapping back.
type Executor ¶
type Executor interface {
// TargetAt returns the desired virtual user count at an elapsed offset
// from the run's start.
TargetAt(elapsed time.Duration) int
// Duration is how long the profile runs. Zero means unbounded, and the
// run ends only on an iteration cap or an explicit stop.
Duration() time.Duration
// Peak is the highest virtual user count the profile ever reaches.
Peak() int
// Describe renders the profile for logs and the dashboard.
Describe() string
}
Executor turns a load profile into a virtual user count at any point in a run.
It is a pure function of elapsed time, deliberately. Every node evaluates the same profile against the same agreed start instant and arrives at the same curve, so ramping needs no per-tick coordination and a node that misses messages for a few seconds rejoins the curve exactly where it should be rather than where it left off.
func NewExecutor ¶
func NewExecutor(profile *loadwavev1.LoadProfile) (Executor, error)
NewExecutor builds the executor described by a load profile.