You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit eeffb42
Browse filesBrowse the repository at this point in the historyBrowse files
benchmarking(boomer): let each user class own its slice of the runtime config
dynconfig had become one struct of every knob every user class ever
needed, with a payload mirror, a merge, a validator, and a log line that
all had to grow by hand for each new field, and every class saw and was
checked against every other class's knobs.
The payload is now an arbitrary JSON object, and a worker runs exactly one
user class, known at launch. So each class declares the keys it reads as a
struct with json tags, wraps it in a dynconfig.Typed codec with its
defaults and its validation func, and registers the codec with its
userclass.Entry. The worker builds the holder from that codec; the holder
stores the typed value, decodes each payload over the class's defaults,
refuses a payload the class cannot run on in favor of the last good
config, and hands the class its knobs back through dynconfig.Get. Keys the
class does not name are ignored. The wait window and the resume and
lifecycle modes are shared pieces a class embeds; durations travel as
seconds, the unit the locust flags use, and print as durations in the
applied-config log line.
Each payload stands on its own. The master serves every flag it knows,
null for the ones the operator left blank, so a field cleared in the web
form takes its knob back to the class default. The old merge over the
running value kept the last set value instead, with no way back to the
default short of a restart. The startup --config-json still names only
the keys the run sets, and the rest start at the defaults as before.
The GluttonUser defaults the worker used to seed from main.go (a 500ms
max wait, one ping per wake) live in that class's codec now, and the
durdir read modes move into the glutton package with the class that reads
them.
Copy file name to clipboardExpand all lines: cmd/benchmarking/boomer-worker/main.go
+15-16Lines changed: 15 additions & 16 deletions
Original file line number
Diff line number
Diff line change
@@ -47,7 +47,7 @@ func main() {
47
47
routerURL=flag.String("router-url", "http://atenet-router.ate-system.svc.cluster.local", "atenet HTTP router base URL (no trailing slash).")
48
48
atespace=flag.String("atespace", "benchmark", "Atespace every actor this worker creates lives in. Ensured (CreateAtespace, AlreadyExists is ok) at startup.")
49
49
promAddr=flag.String("prometheus-addr", ":8001", "Address for the Prometheus /metrics endpoint.")
50
-
configJSON=flag.String("config-json", "", "Initial dynconfig as a JSON object (keys: trace_probability, min_wait_time, max_wait_time, min_live_time, max_live_time in seconds, durdir_file_size_bytes, resume_mode, lifecycle_mode, durdir_read_mode, durdir_template, mem_target, mem_churn, mem_read, cpu_cores, cpu_duty_cycle, max_pings_per_wake). Unset fields keep their built-in defaults.")
50
+
configJSON=flag.String("config-json", "", "Initial dynconfig as a JSON object keyed by locust flag name in snake_case (trace_probability, min_wait_time, ...); the selected user class reads the keys it documents and ignores the rest. Unset keys keep the class's built-in defaults. Each payload the master serves later stands on its own in the same way, so a key it leaves null is back at the default.")
51
51
masterWebPort=flag.Int("master-web-port", 0, "If non-zero, fetch dynconfig from http://{master-host}:{master-web-port}/boomer-config on each spawn message. Exits if the first fetch fails; later failures keep the last fetched values. {master-host} comes from boomer's existing --master-host flag.")
52
52
configPollInterval=flag.Duration("config-poll-interval", 10*time.Second, "With --master-web-port, also fetch dynconfig on this interval. A spawn message comes only when the number of users or the spawn rate changes, thus a load shape that changes the sample rate alone needs this. Zero stops the polling.")
53
53
userClass=flag.String("user-class", "glutton", fmt.Sprintf("Locust user class to run, lowercase; one of %s.", strings.Join(userclass.Names(), "|")))
ctl:=&fakeControlClient{suspendErrs: []error{status.Error(codes.FailedPrecondition, "MarkSuspending prerequisite not met (got: ACTOR_STATE_CRASHED)")}}
0 commit comments