Skip to content

[web-console] Keep showing the pipeline metrics while the pipeline is stopping#6687

Open
Karakatiza666 wants to merge 1 commit into
mainfrom
issue6677
Open

[web-console] Keep showing the pipeline metrics while the pipeline is stopping#6687
Karakatiza666 wants to merge 1 commit into
mainfrom
issue6677

Conversation

@Karakatiza666

@Karakatiza666 Karakatiza666 commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Now when the pipeline is stopped the UI continues to display the live metrics up until the connection is broken.
Now when the metrics stream is interrupted the UI shows the banner that warns that connection to metrics was lost. This is different from the existing banner that warned that the pipeline is unavailable.

Testing: manual

Fix #6677

Screencast.From.2026-07-21.18-30-06.webm

@Karakatiza666
Karakatiza666 requested a review from mihaibudiu July 21, 2026 14:36

@mythical-fred mythical-fred left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice refactor and the UX intent is right — keeping the last-known chart on screen while a pipeline is stopping is a real improvement over the current cliff. A few things before this lands:

Blocker: no Vitest coverage. Per Gerd's hard rule on web-console changes, this needs tests. The specific pieces I would want covered:

  1. usePipelineManager.silence(predicate) — verify that (a) errors matching the predicate do not fire toastError but still reject the returned promise, (b) errors not matching still surface a toast, (c) doNotReportIfCancelled still suppresses cause === 'cancelled' / AbortError regardless of predicate. This is the only behaviorally new surface in usePipelineManager.svelte.ts; the rest of +177/-152 is a mechanical wrap into build(), so if silence() is regression-tested the whole refactor is protected.
  2. TabPerformance — component spec (analogous to what you wrote for #6684) asserting the two banner states: metricsAvailable && !activeMetricsStream renders the new "Not receiving live metrics" banner; the existing !isNetworkHealthy banner still wins when the pipeline is unavailable.
  3. status.ts — the Stopping → 'yes' flip is a one-line change but it inverts an existing contract; add/update the isMetricsAvailable unit test so the intent is nailed down and future refactors don't quietly revert it.

Race on mount: activeMetricsStream = $state<ReadableStream | null>(null) starts as null and metricsAvailable is derived from pipeline.current.deploymentStatus which is truthy immediately. So on first mount, before the first await pollingApi.pipelineTimeSeriesStream(...) resolves, metricsStreamInterrupted is true for one frame and the new "reconnecting" banner briefly appears even though nothing is wrong. Two options: (a) initialize with a hasEverConnected gate — banner only shows once we've had at least one successful stream; (b) treat the initial connect as its own state ('connecting' vs 'reconnecting') and only show the banner on 'reconnecting'. Slide transition makes this more visible, not less.

silence() cause-unwrapping: (error as any)?.cause ?? error is the right idea, but note that doNotReportIfCancelled reads error?.cause === 'cancelled' — a string sentinel — while your example expects cause to be an object with error_code. Worth a one-line comment in silence()'s JSDoc noting that cause can be either a string sentinel or an ErrorResponse-shaped object, so predicates should be defensive (which yours is via optional chaining).

Nit: pollingApi is only used for three call sites in TabPerformance.svelte. Naming it noisySilencedApi or bgApi would read better than pollingApi (the metrics stream isn't polling). Ignore if you disagree.

Nit: the slide transition on WarningBanner is a global change — it now animates every banner site, not just this one. Worth a quick pass to confirm the deployment-error banner and the auth banner don't now feel laggy on toggle.

The core design is right and the refactor is clean. Tests + the initial-mount gate would let this go straight in.

const result = _getPipelineSupportBundle(pipelineName, options, onProgress)
return {
cancel: result.cancel,
// Build the API surface against a given error reporter. `.silence()` reuses this to produce a

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this stuff seems to have been shuffled around, but it's not easy to tell what changed

… stopping

Signed-off-by: Karakatiza666 <bulakh.96@gmail.com>

@mythical-fred mythical-fred left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-review at 6da9942 — one new commit that replaces the boolean activeMetricsStream with a three-state metricsStreamState: 'connecting' | 'live' | 'interrupted'.

The race blocker is fixed. metricsStreamInterrupted is now metricsAvailable && metricsStreamState === 'interrupted', so the reconnect banner can no longer flash on first mount before the initial stream connects — exactly the semantics I asked for. The state machine is also easier to reason about than the previous nullable-stream sentinel.

Still open from the previous review:

  1. No Vitest coverage. Nothing changed since the last round: no TabPerformance.spec.ts, no test for usePipelineManager's new silence() variant, no test for the Stopping → 'yes' flip in status.ts. Web-console tests are a hard rule for this repo — every non-trivial change to js-packages/web-console needs Vitest coverage before merge. The three-state transition (connecting → live → interrupted → live) is precisely the kind of thing that benefits from a small test: it's the whole point of the fix and it's easy to regress.
  2. silence() JSDoc. Still doesn't document that cause can be either the string 'cancelled' or an ErrorResponse-shaped object, and callers already have predicates that assume both. A one-sentence note prevents the next contributor from writing an unsafe predicate.
  3. pollingApi naming and global slide transition on WarningBanner — non-blocking nits from the last round, still worth doing while the diff is open.

The design is now right; blocker downgraded to just the missing tests. Once a Vitest file covers the connecting/live/interrupted transitions and the status.ts flip, this is an approve.

REQUEST_CHANGES pending tests.

@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Jul 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[WebConsole] Continue displaying metrics when the pipeline is stopping

3 participants