Documentation
¶
Overview ¶
Derived from reqfleet/shibuya; modified for engine-sdk.
Derived from reqfleet/shibuya; modified for engine-sdk. Package agent runs coordinator-dependent engine adapters.
Platform support ¶
Deployed agents require Linux containers and cgroup resource metrics. Windows clients may import SDK types and use Handler without starting an agent. On non-Unix systems, AgentServer.Run returns an error matching errors.ErrUnsupported before starting workers, subscriptions, or HTTP services. Workload execution requires Unix process-group supervision.
Coordinator authority ¶
An agent is not a standalone runner. The coordinator authorizes preparation, start and stop, and supplies an explicit RunSpec for the addressed agent. Settings are already resolved: adapters must not interpret VU scope, redistribute load, infer settings from topology or manufacture a missing assignment. Native settings may already be rendered into coordinator-provided configuration files. Artifact assignments are per file, not derived from the agent's identity. Materialized input has already been partitioned; native input requires the engine to apply the exact supplied shard. Replicated input is consumed whole.
Callback order and ownership ¶
PrepareDependencies receives the staged dependency declaration, if any. An absent declaration still invokes reconciliation to remove prior dependencies. A coordinator preparation barrier may separate this stage from start. Execution artifacts are staged before BeforeStart, then BuildCommand returns the primary command. No callback launches or reaps the primary workload; the runtime owns it. Context paths are absolute. Inputs, results and temporary files are reset per run. State and dependency reconciliation files survive. The current runtime serializes runs and reuses the existing image paths only after cleanup ends.
Observe and Progress run after launch, on separate polling loops, outside the runtime lock. Live Progress uses the monitor's cancellation context, allowing summaries to outlast individual observation probes without delaying readiness or status requests. Their read-only RunContext remains valid until each callback returns. Callbacks must honor context cancellation, including child processes. They may cache engine-private summaries by RunID, but must not mutate the supplied settings or artifact maps. BuildCommand is required; other hooks are optional. Without Observe, a successful launch acknowledges readiness.
Outcomes and shutdown ¶
Startup acknowledgement and terminal outcome are independent. WorkComplete acknowledges that startup succeeded but cannot override a failed process. A successful short run completes even if readiness was never polled. A nonzero exit after readiness is an execution failure. Optional progress cannot change lifecycle state or make the status endpoint unavailable. Progress payloads must be valid JSON and identify their engine schema; aggregation belongs to the coordinator. After canceling and joining the live monitors, the runtime captures a final progress snapshot with a fresh two-second context. Adapters should reuse cached summaries/checkpoints rather than restart canceled long-running work.
Stop targets a run and carries the coordinator's reason: scheduled completion or cancellation. Preparation cancellation prevents launch. The runtime retains ownership while callbacks roll back or terminate child processes. For a running workload, Stop receives a fresh context bounded by StopTimeout (ten seconds by default). Without Stop the runtime sends SIGTERM to the process group; after the grace period it sends SIGKILL. Stop must honor its context and must not wait on the primary process. The runtime reaps it, terminates remaining descendants and joins all callbacks/readers before releasing the workspace for another run.
Duplicate requests do not execute a run twice. Retired run IDs are remembered for the agent process lifetime. A stale stop or callback cannot affect a newer run. A new run cannot start while preparation, execution or cleanup is active. Run-scoped progress acknowledges a stopped run only after its worker has finished cleanup. A stop received before preparation tombstones that run ID.
Metrics integration ¶
Adapters either map result-file events with MetricParser, explicitly declare MetricsSchemaShibuyaV1 for an adapter-normalized MetricsHandler or MetricsURL, or expose the registry without request ingestion. These sources are mutually exclusive; a Prometheus handler or URL alone is not a schema mapping. See the metrics contract for names, units, labels, bucket profiles, accumulation semantics, and built-in adapter limitations.
Runtime label admission uses AgentServerOptions.LabelsUsageLimit, not coordinator run messages. LoadAgentServerOptions resolves the lowercase label_limit environment variable (default 10 when unset or empty); MakeAgentServer uses the same loader. NewAgentServer uses the resolved option directly, including zero. Adapters can initialize native exporters from those options before construction. The SDK has no tier policy. Workloads inherit label_limit if present; Command.Env may override it. The SDK does not rewrite it from LabelsUsageLimit. Native engines enforce their own configured limits. Native proxying streams by default without parsing, format negotiation, validation, or SDK label admission. MetricsHandler serves directly behind the SDK's GET /metrics authentication, preserving the incoming request context and the handler's status, headers, and body, including errors. It does not proxy, parse, fold, cache, or merge output. The adapter owns parsing, normalization, label limits, concurrent access, run-local exporter state, final-scrape retention, and exporter shutdown; the SDK owns the listener. ResultFile may still name workload output without a parser.
FoldNativeMetrics explicitly enables last-resort SDK folding for URL-backed native engines that cannot enforce the budget. It and NativeMetricsOverflowLabel require MetricsURL and cannot be used with MetricsHandler or registry ingestion. Folding buffers and parses each Prometheus text snapshot (at most 16 MiB), validates safe aggregation, and re-encodes the result. Invalid snapshots fail rather than bypassing admission. Admission is stable across scrapes; colliding cumulative counters and histograms are aggregated within each snapshot, not added again across snapshots. The producer must retain cumulative source series for the run. NativeMetricsOverflowLabel defaults to "others"; Replay's engine-owned overflow convention is "_other_". Replay handles its limits through config.yaml with SDK folding disabled. Its native max_labels=0 setting remains unlimited.
With folding enabled, admission survives completion for final scrapes and resets on the next successful workload launch; the producer must still be reachable. This bounds exported request labels, not producer memory, other dimensions, or plan-wide labels across agents. Result-file ingestion and opt-in folding permit N named labels plus one overflow label; zero permits only overflow in these SDK-managed modes. Upload validators return optional preflight counts to the calling control plane without tier or label-limit inputs; those counts do not guarantee runtime cardinality.
Derived from reqfleet/shibuya; modified for engine-sdk.
Derived from reqfleet/shibuya; modified for engine-sdk.
Derived from reqfleet/shibuya; modified for engine-sdk.
Derived from reqfleet/shibuya; modified for engine-sdk.
Derived from reqfleet/shibuya; modified for engine-sdk.
Derived from reqfleet/shibuya; modified for engine-sdk.
Derived from reqfleet/shibuya; modified for engine-sdk.
Index ¶
Constants ¶
const (
FILEMODE = 0700
)
Variables ¶
var STDERR = "/dev/stderr"
Functions ¶
This section is empty.
Types ¶
type AgentDir ¶
type AgentDir struct {
// contains filtered or unexported fields
}
func NewAgentDirHandler ¶
func (AgentDir) ConfFilesDir ¶
func (af AgentDir) ConfFilesDir() ConfFilesDirectory
func (AgentDir) Dir ¶
func (af AgentDir) Dir() AgentDirectory
func (AgentDir) ResultFilesDir ¶
func (af AgentDir) ResultFilesDir() ResultFilesDirectory
func (AgentDir) TestFilesDir ¶
func (af AgentDir) TestFilesDir() TestFilesDirectory
type AgentDirectory ¶
type AgentDirectory string
func (AgentDirectory) Filepath ¶
func (af AgentDirectory) Filepath(sub ...string) string
type AgentServer ¶
type AgentServer struct {
// contains filtered or unexported fields
}
func MakeAgentServer ¶
func MakeAgentServer(options AgentServerOptions) *AgentServer
MakeAgentServer loads environment-backed options using LoadAgentServerOptions, then constructs a server with NewAgentServer. It logs fatally on configuration errors. Call LoadAgentServerOptions directly to handle errors without exiting or to configure adapter components before constructing the server.
func NewAgentServer ¶
func NewAgentServer(opts AgentServerOptions) *AgentServer
NewAgentServer constructs a server from explicit options without reloading the environment-backed settings handled by LoadAgentServerOptions. It does not start listeners or workloads; call Run to start the agent. A zero LabelsUsageLimit is used as-is, not replaced with a default.
func (*AgentServer) Handler ¶
func (as *AgentServer) Handler() http.Handler
Handler returns the authenticated agent HTTP endpoints. Health checks bypass authentication.
func (*AgentServer) Run ¶
func (as *AgentServer) Run() error
func (*AgentServer) SubscribeToCoordinator ¶
func (as *AgentServer) SubscribeToCoordinator() (chan protocol.Message, error)
type AgentServerOptions ¶
type AgentServerOptions struct {
EngineMeta EngineMeta
CoordinatorRootCAs *x509.CertPool
TestFileName string
DependencyFileName string
PrepareDependencies func(context.Context, RunContext) error
BeforeStart func(context.Context, RunContext) error
BuildCommand func(context.Context, RunContext) (Command, error)
Observe func(context.Context, RunContext) (protocol.Observation, error)
Progress func(context.Context, RunContext) (protocol.Progress, error)
Stop func(context.Context, RunContext, Process) error
StopTimeout time.Duration
// MetricsURL proxies an external normalized endpoint; it cannot be combined
// with MetricsHandler or MetricParser.
MetricsURL string
// MetricsHandler serves normalized metrics directly at the authenticated
// GET /metrics route, using the incoming request and response writer.
// It requires NativeMetricsSchema and cannot be combined with MetricsURL,
// MetricParser, FoldNativeMetrics, or NativeMetricsOverflowLabel.
// ResultFile may still name workload output; the SDK does not tail it.
// The adapter owns normalization, label limits, concurrent access, run-local
// state, and exporter shutdown. The SDK owns the HTTP listener and does not
// parse, merge, cache, or close the handler's output or state.
MetricsHandler http.Handler
// NativeMetricsSchema declares the profile supplied by MetricsURL or MetricsHandler.
NativeMetricsSchema MetricsSchema
// FoldNativeMetrics opts into SDK parsing and label folding for MetricsURL
// as a last resort. It requires MetricsURL. By default the native endpoint
// streams unchanged and the engine must enforce its own configured label limit.
FoldNativeMetrics bool
// NativeMetricsOverflowLabel selects the folding fallback's overflow name.
// It requires MetricsURL and defaults to "others"; use "_other_" for Replay's convention.
NativeMetricsOverflowLabel string
MetricParser func(string) (ShibuyaMetric, error)
ResultFile string
Logger *log.Entry
ConfFileName string
LabelsUsageLimit int
}
AgentServerOptions configures an adapter, not an independent execution mode. Callbacks must honor cancellation and must not retain mutable run data beyond their return. The runtime waits for callbacks and cleanup before another run.
func LoadAgentServerOptions ¶ added in v0.4.0
func LoadAgentServerOptions(options AgentServerOptions) (AgentServerOptions, error)
LoadAgentServerOptions resolves SDK-owned environment settings before server construction. It does not log, terminate the process, start services, or validate adapter callbacks and metrics integration. On error it returns zero options; the caller's options are not modified.
Precedence and validation match MakeAgentServer:
- LabelsUsageLimit is always replaced by label_limit, or 10 when that variable is unset or empty, even if the input option is nonzero. Nonempty values use strconv.Atoi: decimal digits with an optional sign, no surrounding whitespace, within the platform int range. Negative results are rejected; 0, +0, -0, and +1 are valid. Zero permits only the overflow label in SDK-managed modes.
- A non-nil CoordinatorRootCAs is preserved and coordinator_ca_cert is ignored. Otherwise coordinator_ca_cert must contain at least one parseable PEM certificate. Unset, empty, whitespace-only, and malformed values are errors.
- A nonzero EngineMeta is preserved as a whole, without filling missing fields or validating it. Otherwise engine_name must have five hyphen-separated components with an integer fifth component, and offset must be an integer. Both integers use strconv.Atoi; unset, empty, malformed, and overflowing integers are errors. EngineID is their sum, formatted in decimal. coordinator_ip, collection_id, zone, plan_id, and api_key are copied as-is; unset and empty values both become empty strings, without validation.
All other options are preserved. To override a resolved value (including a zero label limit), assign it after loading. Configure adapter-owned components from the resolved options, then pass them to NewAgentServer, not MakeAgentServer, to avoid another environment read.
type ConfFilesDirectory ¶
type ConfFilesDirectory string
func (ConfFilesDirectory) Filepath ¶
func (cf ConfFilesDirectory) Filepath(sub ...string) string
type EngineMeta ¶
type MetricsSchema ¶
type MetricsSchema string
MetricsSchema identifies the reporting profile promised by a native adapter.
const MetricsSchemaShibuyaV1 MetricsSchema = "shibuya-v1"
type Process ¶
type Process struct {
PID int
}
Process identifies the runtime-owned primary workload. Stop callbacks may request shutdown but must not reap it; the runtime owns waiting and escalation.
type ResultFilesDirectory ¶
type ResultFilesDirectory string
func (ResultFilesDirectory) ResultFile ¶
func (rf ResultFilesDirectory) ResultFile(sub ...string) string
type RunContext ¶
type RunContext struct {
RunID string
CollectionID string
PlanID string
AgentID string
Zone string
Workspace Workspace
TestFile string
ConfigFile string
DependencyFile string
ResultFile string
Settings json.RawMessage
Artifacts map[string]protocol.ArtifactAssignment
}
RunContext is a read-only snapshot supplied to each adapter callback. Settings and artifact assignments come from the coordinator, without allocation or fallback inference in the agent. Paths are resolved locally by the runtime. DependencyFile is empty when the coordinator supplies no declaration; dependency preparation must still reconcile any installation left by a previous run.
type ShibuyaMetric ¶
type ShibuyaMetric struct {
Label string
Status string
Raw string
CollectionID string
PlanID string
EngineID string
RunID string
Zone string
Threads float64
Latency float64
EgressBytes float64
}
func (ShibuyaMetric) LabelIsValid ¶
func (sm ShibuyaMetric) LabelIsValid() (bool, error)
Cortex has the limit for metric label values for 2048 We set the limit to half of it. 1024 is already pretty long for any valid label(test) names
func (ShibuyaMetric) LabelLength ¶
func (sm ShibuyaMetric) LabelLength() int
func (ShibuyaMetric) ToPrometheus ¶
func (sm ShibuyaMetric) ToPrometheus()
type TestFilesDirectory ¶
type TestFilesDirectory string
func (TestFilesDirectory) Filepath ¶
func (tf TestFilesDirectory) Filepath(sub ...string) string
type Workspace ¶
type Workspace struct {
Root string
Inputs string
Config string
Results string
Temp string
State string
}
Workspace separates run files from reusable engine/dependency state. A runtime executes one run at a time; it may reuse physical paths only after all callbacks, processes and cleanup from the preceding run have finished.