Skip to content

Commit d99826e

Browse files
committed
Measure saturated upstream block load
1 parent 84ed22e commit d99826e

2 files changed

Lines changed: 56 additions & 12 deletions

File tree

.github/workflows/upstream-runtime-comparison.yml

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -930,11 +930,16 @@ jobs:
930930
mean_nonregression = float(mean["ratioBootstrap95Ci"][1]) <= 1.05
931931
p95_nonregression = float(p95["ratioBootstrap95Ci"][1]) <= 1.05
932932
p99_nonregression = float(p99["ratioBootstrap95Ci"][1]) <= 1.10
933+
candidate_tps_healthy = all(
934+
19.9 <= float(value["observedTps"]) <= 20.5
935+
for value in metrics_by_variant["B"]
936+
)
933937
scenario_passed = formal and all((
934938
primary_improvement,
935939
mean_nonregression,
936940
p95_nonregression,
937941
p99_nonregression,
942+
candidate_tps_healthy,
938943
))
939944
if not formal:
940945
conclusion = "exploratory-no-winner"
@@ -954,11 +959,20 @@ jobs:
954959
"",
955960
f"A is official upstream Jenkins #163; B is production candidate "
956961
f"`{candidate_source[:7]}`. ",
957-
"Smoke evidence is exploratory and never declares a winner.",
962+
("Formal evidence is evaluated against the pre-registered gates."
963+
if formal else
964+
"Smoke evidence is exploratory and never declares a winner."),
958965
"",
959966
"| Metric | Upstream median | Rewrite median | Median B/A | Ratio 95% CI | Registered use |",
960967
"|---|---:|---:|---:|---:|---|",
961968
]
969+
if formal and scenario == "block-active":
970+
lines[5:5] = [
971+
"Load-regime rule: sustained block load may saturate official upstream A "
972+
"when the 120-second window still contains at least 100 tick samples; "
973+
"candidate B must remain in the 19.9-20.5 TPS regime.",
974+
"",
975+
]
962976
for metric, unit in metric_specs:
963977
analysis = analyses[metric]
964978
a_median = statistics.median(float(value[metric]) for value in metrics_by_variant["A"])
@@ -986,7 +1000,12 @@ jobs:
9861000
"",
9871001
f"Scenario conclusion: **{conclusion}**.",
9881002
"",
989-
"`observedTps` is capped near 20 on a healthy server; MSPT is the primary effect-size evidence.",
1003+
("Candidate `observedTps` must stay near 20; saturated upstream throughput is "
1004+
"reported directly for the sustained block load. MSPT remains the primary "
1005+
"effect-size evidence."
1006+
if formal and scenario == "block-active" else
1007+
"`observedTps` is capped near 20 on a healthy server; MSPT is the primary "
1008+
"effect-size evidence."),
9901009
"",
9911010
f"- Upstream source/artifact: `{upstream_source}` / `{upstream_artifact}`",
9921011
f"- Candidate source/artifact: `{candidate_source}` / `{candidate_artifact}`",
@@ -1025,6 +1044,17 @@ jobs:
10251044
"ratioCiUpperMaximum": 1.10,
10261045
"passed": p99_nonregression if formal else None,
10271046
},
1047+
"candidateHealthyTps": {
1048+
"minimum": 19.9,
1049+
"maximum": 20.5,
1050+
"passed": candidate_tps_healthy if formal else None,
1051+
},
1052+
},
1053+
"loadRegimePolicy": {
1054+
"upstreamSaturationAllowed": formal and scenario == "block-active",
1055+
"minimumUpstreamTickSamples": (
1056+
100 if formal and scenario == "block-active" else None
1057+
),
10281058
},
10291059
"metrics": {
10301060
metric: {

tools/perf/run-upstream-runtime-once.sh

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -561,17 +561,31 @@ if data.get("seconds", 0) < measure - 2 or data.get("seconds", 0) > measure + 3:
561561
raise SystemExit(f"comparison measurement duration is invalid: {data.get('seconds')}")
562562
if data.get("tickSamples", 0) <= 0 or data.get("observedTps", 0) <= 0:
563563
raise SystemExit("comparison produced no valid tick samples")
564-
minimum_tps = 19.9 if measure >= 60 else 19.5
565-
if not minimum_tps <= data["observedTps"] <= 20.5:
566-
raise SystemExit(
567-
f"comparison did not remain in the healthy 20 TPS regime "
568-
f"({minimum_tps}..20.5): {data['observedTps']}"
569-
)
570-
minimum_tick_samples = (
571-
math.floor(data["seconds"] * minimum_tps)
572-
- data["boundaryTickSamplesDiscarded"]
573-
- 1
564+
allows_upstream_saturation = (
565+
measure >= 60 and scenario == "block-active" and variant == "A"
574566
)
567+
if allows_upstream_saturation:
568+
# Sustained block load is allowed to expose the official upstream's
569+
# throughput ceiling. The rewritten candidate remains subject to the
570+
# healthy-20-TPS guard, and the upstream sample must still contain enough
571+
# tick observations for stable percentile estimates.
572+
if data["observedTps"] > 20.5:
573+
raise SystemExit(
574+
f"comparison exceeded the server TPS ceiling: {data['observedTps']}"
575+
)
576+
minimum_tick_samples = 100
577+
else:
578+
minimum_tps = 19.9 if measure >= 60 else 19.5
579+
if not minimum_tps <= data["observedTps"] <= 20.5:
580+
raise SystemExit(
581+
f"comparison did not remain in the healthy 20 TPS regime "
582+
f"({minimum_tps}..20.5): {data['observedTps']}"
583+
)
584+
minimum_tick_samples = (
585+
math.floor(data["seconds"] * minimum_tps)
586+
- data["boundaryTickSamplesDiscarded"]
587+
- 1
588+
)
575589
if data["tickSamples"] < minimum_tick_samples:
576590
raise SystemExit(f"comparison recorded too few tick samples: {data['tickSamples']}")
577591
for key in ("msptP50", "msptP95", "msptP99", "msptP999", "msptMax", "msptMean"):

0 commit comments

Comments
 (0)