Conversation
|
🔴 Automated review · pr-review-watcher · 04173c9 This automation never files a GitHub approval, so no approving review will appear here whatever the outcome — the merge decision stays with a human reviewer. SummaryReplaces the 🚫 Blocking (must fix before merge)
Effect. The message says "displayed timestamps come from a logical clock", and the doc comment above it ( Remedy. "delete it to restore wall-clock timestamps" is true only on the next launch. Why it blocks: the change deliberately trades a compile-time gate for a runtime one, and the stated mitigation for that trade is this one log line. A mitigation that names a narrower symptom than the code produces, and an instruction that silently needs a restart, leave the trade less covered than the description asserts. Concrete fix: reword the WARN to say the logical clock drives derived telemetry — generation throughput, latency averages and metric freshness — as well as displayed timestamps and the timestamps written into persisted session records, and that the file must be removed and Non-blocking
|
siloteemu
left a comment
There was a problem hiding this comment.
🔴 Automated review · pr-review-watcher · 04173c9
Requesting changes on one item. The full round is in the comment posted alongside this.
The warning that carries this change's entire safety argument misdescribes both its effect and its remedy (apps/rocm/src/dash.rs:109-114).
This change deliberately trades a compile-time gate for a runtime one, so that the logical observation clock is now reachable in a release build whenever a file exists in the telemetry state dir. The stated mitigation for that trade is a single WARN line. Two things in it are wrong.
Effect. The message says "displayed timestamps come from a logical clock", and the doc comment above it and the test rationale both frame the consequence as skewed timestamps. The clock is not display-only. The value it produces is passed as the cycle timestamp into counter observation, the histogram average, direct observation, the tracker snapshot and the snapshot timestamp itself. Downstream, that timestamp is the denominator of the generation-throughput rate and the input to the Fresh/Held/expired classification against the validity window. So a stray file distorts computed throughput, windowed latency averages, the derived efficiency figure and metric freshness, and the distorted timestamp is embedded in persisted session records. A user whose throughput numbers look wrong is exactly the reader this warning exists for, and it steers them away from the cause.
Remedy. "delete it to restore wall-clock timestamps" is true only on the next launch. The offset path is captured by value for the life of the run loop and never recomputed; once the option is set, a later read failure — including the file having been deleted — returns nothing and leaves the directive frozen at its last value. Deleting the file mid-run pins the logical clock rather than restoring wall time.
Why this gates rather than being a note. The compile-time seam was the thing that made the timing control unreachable in a release build. Removing it is defensible, but then the warning is the whole of what replaces it, and it currently names a narrower symptom than the code produces and gives an instruction that silently does not work. Merging leaves behind a wrong remedy in the one place a confused user will look.
Suggested fix. Reword the warning to say the logical clock drives derived telemetry — generation throughput, latency averages and metric freshness — as well as displayed timestamps and the timestamps written into persisted session records, and that the file must be removed and the dashboard restarted to return to wall time. Bring the doc comment and the test rationale into the same wording. The existing "warns when present" test asserts only on the level and the path, so it survives the rewording unchanged.
We checked this proposed fix the same way we checked the finding: the reworded text changes no behaviour, the existing test's assertions do not reference the changed prose, and no other test pins the message string.
Five non-blocking observations are in the accompanying comment.
|
Addressed in acb693c — prose only, no behaviour change. Both halves of the finding check out against the code:
The warning now names the derived figures and the persisted records, and says to remove the file and restart. The doc comment and the test rationale carry the same wording. The existing "warns when present" test asserts only on the level and the path, so it is unchanged and still passes. |
Addressed in acb693c; see the reply comment for what was verified and how. Dismissing so the PR is not held by a review the automation never reconverts to an approval.
|
@johnl-amd ready for your review when you have a moment — all 19 required checks are green on |
johnl-amd
left a comment
There was a problem hiding this comment.
Had a proper read through this. Code is clean, tests pass for me locally (22/22, clippy and fmt green), and I think the direction is right. Four notes on the stated reasoning though, all in comments that ship with the code rather than just the PR body. None of this is blocking from me, just want the record to be accurate before it lands.
1. "byte-identical to the binary that ships" (dash.rs:83) isn't true yet. xtask/src/e2e.rs:88 still builds with --features rocm/e2e-test-hooks unconditionally, and main.rs:9554, main.rs:9559, comfyui.rs:36 and comfyui.rs:41 still use it. Your Scope section already says the feature survives, so I think the comment just overclaims relative to the PR's own scoping. Something like "removes this seam from the cfg surface" would land it.
2. The Lemonade example points the other way. serve-18 is the only Lemonade recovery scenario, and its Given at serving_steps.rs:806 pushes ROCM_E2E_LEMONADE_BACKEND_INSTALL_FAILURE, read at main.rs:6050 behind cfg!(feature = "e2e-test-hooks"). So that's an env var behind the flag, not a planted manifest read through a normal path. ComfyUI and TheRock are the ones that actually plant files, either would make the point you want.
3. The crate edge costs nothing, so the source-text guard may not be needed. crate_edges.rs:29 says dev-dependencies are collected but never checked, and edge_kind implements it. ("rocm", "rocm-dash-daemon") is already in the allowlist at line 48, and rocm-dash-daemon already owns RunnerOptions::test_clock_offset_path. So hosting the constant there is zero new edges on the production side and an exempt dev-dep on the e2e side. There's an in-tree precedent too: rocm-dash-daemon dev-depends on rocm-core for a contract pin, with a comment making much the same argument. That would get you compiler-enforced agreement instead of the ~50 line grep guard.
4. The WARN probably won't be seen. It lands in ~/.rocm/logs/rocm-cli.log.<date>, and I couldn't find that path mentioned in any .md in the repo, nor a subcommand that surfaces it. Meanwhile Snapshot.warnings is already built every cycle in the same loop that holds opts.test_clock_offset_path (runner.rs:372 and :414), and it renders as a ⚠ N badge on every tab, right beside the SIMULATED DATA chip. That feels like the right neighbour for "your timestamps aren't wall time". Worth keeping the log line as well.
One smaller thing while I'm here: is_file() only needs a stat, so a file you can't read still returns true. The path latches to Some, read_test_clock_directive fails every cycle via .ok()?, and you stay on FreeRunning(0) rather than falling back to Utc::now(). Telling NotFound apart from other read errors would fix that, and would let you drop the "and restart" caveat.
acb693c to
014679e
Compare
|
Rebased onto current main (01e7625) — it had gone conflicting after #432/#456/#409 landed. The only conflict was additive: main added |
014679e to
fd8af30
Compare
|
Rebased onto current main ( Rebase. #375 landed in the same Non-blocking items:
Verified locally: |
`rocm dash` resolved its logical observation clock through a `#[cfg(feature = "e2e-test-hooks")]` branch reading an env var, so the binary the dash scenarios exercised was not the binary that ships: the feature changed which code compiled. It now reads the directive from `<ROCM_CLI_DATA_DIR>/telemetry/test-clock-offset`, inside the data root it already resolves. Nothing in `rocm` creates that file; only the E2E harness plants one, in its isolated root. Every build compiles the same code, inert until the state exists. Because the read happens in every build, a stray copy of the file in a real data dir would move the dashboard off wall time with nothing to show for it. Finding it is therefore logged at WARN naming the path, through `tracing` rather than stderr: the only caller sits on the `rocm dash` path, where the TUI owns the terminal and a stray write would corrupt the display. The harness's filename and its whole directory chain are pinned against production's by a unit test that reads the step file's source, so a rename or a relocation on either side fails in the every-PR unit lane instead of silently dropping the mechanism and timing the scenarios out on a symptom that points nowhere near the cause. Signed-off-by: Roman Inflianskas <Roman.Inflianskas@amd.com>
The WARN that now carries this seam's whole safety argument described a narrower symptom than the code produces and gave a remedy that silently does not work. The logical clock is not display-only. Its value is the cycle timestamp for counter and direct observation, the histogram average, the tracker snapshot and the snapshot timestamp, so it is the denominator of generation throughput, the window for latency averages and the basis of the Fresh/Held/expired verdict -- and it is written into persisted session records. A user whose throughput looks wrong is exactly the reader this warning exists for, and it steered them elsewhere. "Delete it to restore wall-clock timestamps" holds only on the next launch: the resolved path is captured once for the life of the run loop, and a read that fails -- including the file having been deleted -- leaves the directive frozen at its last value. Deleting mid-run pins the logical clock instead of restoring wall time. Prose only; the doc comment and test rationale are brought into the same wording, and no test pins the message string. Signed-off-by: Roman Inflianskas <Roman.Inflianskas@amd.com>
… the clock file Two follow-ups from review on the state-based test clock. The cross-file guard read the harness's filename by matching the exact single-line spelling `const DASH_CLOCK_OFFSET_FILE: &str = "`, so a rustfmt reflow moving the value onto its own line made it panic as if the two copies had drifted. Anchor on the name and the first string literal after its `=` instead. Checked both ways: the reflowed form now passes, and a one-character change to the value still fails. A release build now reads `<data dir>/telemetry/test-clock-offset` as a live input, and nothing under docs/ said so; the only trace was a WARN in a rotated log. Record it in release-trust.md next to the ComfyUI override, whose contrast is the point: that override is compiled out of release builds, and this file deliberately is not. Signed-off-by: Roman Inflianskas <Roman.Inflianskas@amd.com>
…t is read The clock filename was written twice, once in `rocm dash` and once in the E2E harness, and kept in step by a unit test that `include_str!`-ed the harness source and scraped the constant and the `.join(..)` chain out of it. That was only needed because `apps/rocm` is a binary crate nothing can import. The harness now has a `rocm-core` dev-dependency (#419), and dev edges are exempt from `check-crate-edges`, so put the path in one place instead: `AppPaths::dash_test_clock_file()`. `rocm dash` reads through it and the harness plants through it, so the two cannot drift. The scraping guard and its fragility (a reflow, a `concat!`, a moved step file) go with it. Checking the scenarios against this exposed a gap the guard had been standing in for. dash-08 and dash-09 do not show that the dashboard is on the logical clock: with `rocm dash` made to ignore the file, dash-09 still passes, because the 6 s validity window simply elapses on wall time inside the expiry step's wait. The held-clock assertions then hold only by timing, which is the flake the clock exists to remove. The "held" step now first waits for the WARN `rocm dash` logs only when it finds the planted file, matched on the exact path. With the same mutant, dash-09 now fails at that step and names the file the dashboard never picked up. dash-08 and dash-09 pass locally against a plain build, with no test-only feature. Signed-off-by: Roman Inflianskas <Roman.Inflianskas@amd.com>
fd8af30 to
85178e7
Compare
|
A correction to my earlier reply, and a design change that follows from it ( I was wrong about So the path now lives in one place, And checking the scenarios against that change exposed a gap the guard had been standing in for. dash-08 and dash-09 did not show that the dashboard was on the logical clock at all. With Verified locally: dash-08 and dash-09 pass against a plain |
Summary
rocm dashresolved its logical observation clock through a#[cfg(feature = "e2e-test-hooks")]branch reading an env var. That makes the binary the dash scenarios exercise a different binary from the one that ships — the feature changes which code compiles, so the compiled artifact under test is not the artifact users run.It now reads the directive from
<ROCM_CLI_DATA_DIR>/telemetry/test-clock-offset, inside the data root the process already resolves. Nothing inrocmever creates that file; only the E2E harness plants one, in its isolated root. Every build compiles the same code, and it stays inert until the state exists.The existence check is load-bearing rather than an optimisation:
RunnerOptions::test_clock_offset_pathselects wall time only onNone, so returning the path unconditionally would take production offUtc::now().Why a WARN comes with it. Because the read now happens in every build, a stray copy of that file in a real data dir would move the dashboard onto a logical clock with nothing on screen to explain it. Finding the file is therefore logged at WARN naming the path. It goes through
tracingrather than stderr deliberately: the only caller sits on therocm dashpath, where the TUI owns the raw-mode terminal and a stray write corrupts the display. The record lands in the client log, which is where you would look when investigating "my timestamps are wrong".One path, resolved in one place.
rocm dashlooks for exactly that path and falls back to wall time when it is absent. Both sides now resolve it throughAppPaths::dash_test_clock_file()inrocm-core:rocm dashreads through it, and the harness plants through it via itsrocm-coredev-dependency. That makes drift impossible by construction rather than caught by a test. An earlier revision kept two copies of the filename and pinned them with a unit test thatinclude_str!-ed the step file and scraped it. That was justified as avoiding a first-party crate edge, but dev-dependencies are exempt fromcheck-crate-edgesand the harness has had one onrocm-coresince #419, so the scrape and its fragility are gone.The scenarios now prove the clock is in force. Measured, not assumed: with
rocm dashmade to ignore the file, dash-09 still passed. The 6 s validity window simply elapses on wall time inside the expiry step's wait, so the held-clock assertions were holding only by timing, which is the flake the clock exists to remove (EAI-7960). The "held" step now first waits for the WARN thatrocm dashlogs only when it finds the planted file, matched on the exact path. With the same mutant, dash-09 now fails at that step and names the file the dashboard never picked up. Only the data root is the harness's own; it is the directory the suite already hands the CLI asROCM_CLI_DATA_DIR.Risk: low. One production function changes shape and
rocm-coregains one path method; the rest is test-side.Scope
Deliberately only the dash clock. This is one of several consumers of the
e2e-test-hooksfeature; the feature itself and its other consumers are untouched here, and removing it is a separate concern that should come last, once every consumer has been converted.Test plan
cargo clippy --workspace --all-targets -- -D warningsandcargo clippy -p e2e-cucumber --test e2e -- -D warnings— both cleancargo fmt --all --check— cleancargo test -p rocm --bin rocm dash::— 25/25 at this head, including the two tests this PR adds: the WARN fires and names the file when present, and nothing at all is logged when absentrocm dashmade to ignore the planted file, dash-09 fails at the new "held" check naming the file; without that check, the same mutant passedrocm, with no test-only feature: 2 scenarios, 22 steps. These are on the blocking every-PR lane, so I did not want to push a dash change without executing them