Skip to content

fix(profiler-ui): rehydrate report on mount so split panes keep the chart#1321

Open
dylan-savage wants to merge 1 commit into
developfrom
fix/profiler-split-loses-report-data
Open

fix(profiler-ui): rehydrate report on mount so split panes keep the chart#1321
dylan-savage wants to merge 1 commit into
developfrom
fix/profiler-split-loses-report-data

Conversation

@dylan-savage

@dylan-savage dylan-savage commented Jun 18, 2026

Copy link
Copy Markdown
Collaborator

Problem

Splitting a Profiler tab made both panes show "No profiling data available" even though the status line still read "Idle — report available".

Root cause

Report data (treeData/vizRoot) lived only in ProfilerView local state and was populated solely by the live Stop flow. Splitting (splitGroupWithDocument) mounts fresh ProfilerView instances with empty state. Meanwhile status is server-backed (polled), so has_report stayed true — hence the divergence.

Fix

Add a mount-time effect that calls the existing fetchReport() once (guarded per-target) when connected, not actively profiling, status.has_report is true, but local treeData is empty. This makes report data server-rehydratable like status, so freshly-mounted split panes reload the existing report.

Fixes both the sunburst chart and the stats table (same treeData gate).

Verification

  • Builds via rsbuild.
  • Manual: load a report → split the view → both panes keep the chart + table.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • The profiler view now automatically loads previously captured profiling reports when reconnecting to a session, eliminating empty views and eliminating the need to re-run profiling when returning to an existing session.

…hart

Report data lived only in ProfilerView local state, populated solely by the
live Stop flow. Splitting a tab mounts fresh instances with empty state, so
both panes showed 'No profiling data available' while the status line still
read 'report available' (status is server-backed). Add a mount-time effect
that refetches the existing report when has_report is true but local data is
empty.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

ProfilerView adds a rehydratedTargetRef ref and a mount-time useEffect that calls fetchReport() once per target when the connection is idle, the server reports an existing profiling result, and no local tree data is present.

Changes

Server Report Rehydration

Layer / File(s) Summary
One-shot report rehydration ref and effect
apps/profiler-ui/src/views/ProfilerView.tsx
rehydratedTargetRef is introduced to gate rehydration to one attempt per target. A new useEffect checks !status.active, status.has_report, and the absence of local treeData before calling fetchReport(), then marks the ref so the effect does not fire again for the same target.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Poem

A bunny hops back to the warren at night,
The tree data was missing — oh, what a fright!
One ref keeps the fetch from repeating twice,
A useEffect checks the server — isn't that nice?
Now reports rehydrate at the very first sight! 🐇✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly describes the main change: rehydrating report data on mount to ensure split panes retain chart visibility.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/profiler-split-loses-report-data

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

Copy link
Copy Markdown
🤖 Internal: Discord sync marker

Auto-managed by the Discord notification workflow. Stores the linked Discord message ID. Do not edit or delete.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/profiler-ui/src/views/ProfilerView.tsx`:
- Around line 559-563: The guard condition at line 562 that checks if
treeData?.tree exists doesn't account for target switches. When a new target is
selected, the existing treeData may be stale data from the previous target,
causing the effect to return early without rehydrating the new target's data.
Modify the guard condition to also verify that the existing treeData corresponds
to the current target, not just check if treeData exists. This ensures that when
switching to a new target, the effect will properly proceed to rehydrate that
target's report instead of skipping it due to stale data from the previous
target.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: fa3a7382-64be-47c2-ac55-1550532415c1

📥 Commits

Reviewing files that changed from the base of the PR and between 40bc259 and 80b8181.

📒 Files selected for processing (1)
  • apps/profiler-ui/src/views/ProfilerView.tsx

Comment on lines +559 to +563
if (!isConnected) { rehydratedTargetRef.current = undefined; return; }
if (status?.active === true) return; // a live session owns the data
if (!status?.has_report) return; // nothing on the server to rehydrate
if (treeData?.tree != null) return; // already have data locally
if (rehydratedTargetRef.current === target) return; // already attempted for this target

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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Rehydration guard can skip fetch for a newly selected target.

At Line 562, treeData is treated as globally valid, but target switches can leave stale local tree data from the previous target (Line 678 only changes target). That causes this effect to return early and not rehydrate the new target’s report.

💡 Proposed fix
@@
-				<select
+				<select
 					style={styles.select}
 					value={target || ''}
-					onChange={(e) => setTarget(e.target.value || null)}
+					onChange={(e) => {
+						const nextTarget = e.target.value || null;
+						setTarget(nextTarget);
+						// Clear local report state so rehydration can fetch for the new target
+						setReport('');
+						setTreeData(null);
+						setOriginalRoot(null);
+						setVizRoot(null);
+						setCallStack([]);
+						rehydratedTargetRef.current = undefined;
+					}}
 					disabled={isActive}
 				>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/profiler-ui/src/views/ProfilerView.tsx` around lines 559 - 563, The
guard condition at line 562 that checks if treeData?.tree exists doesn't account
for target switches. When a new target is selected, the existing treeData may be
stale data from the previous target, causing the effect to return early without
rehydrating the new target's data. Modify the guard condition to also verify
that the existing treeData corresponds to the current target, not just check if
treeData exists. This ensures that when switching to a new target, the effect
will properly proceed to rehydrate that target's report instead of skipping it
due to stale data from the previous target.

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.

1 participant