refactor(FR-3351): extract idle-checker classification into a helper module - #9492
Closed
yomybaby wants to merge 2 commits into
Closed
refactor(FR-3351): extract idle-checker classification into a helper module#9492yomybaby wants to merge 2 commits into
yomybaby wants to merge 2 commits into
Conversation
…module The reclamation color classification lived in SessionReclamationStatusPopover while the idle-check payload types lived in SessionIdleChecks, so the two sibling components imported each other. Move both into a dedicated `idleChecks.ts` module: the payload types, `getUtilizationCheckerColor`, `getOverallReclamation`, the severity ordering, the legend constants, `getIdleChecksTagColor` and the `useReclamationColorMap` hook. Neither component imports the other any more. `idle_checks` was JSON-parsed three times for the same session (once per component). It is now parsed once per boundary: `SessionReclamationStatusCell` stays the Relay boundary for the session table and hands the parsed utilization check to the new presentational `SessionReclamationStatus`, which `SessionIdleChecks` renders directly from the payload it already parsed. The popover takes the parsed `UtilizationExtra` as a prop, so its own fragment is gone. The popover body moves into `ReclamationPopoverContent`. Astryx `HoverCard` mounts its content lazily (`useLayer` renders only a `<template>` marker while closed), so the resource-slot lookup and the per-resource/legend rows now run when the card opens instead of for every rendered session row. `UtilizationExtra.resources` is typed as an open map: the manager builds it from the configured resource slots (idle.py `UtilizationResourceReport`), so the previous fixed six-key shape did not describe the payload. Claude-Session: https://claude.ai/code/session_011RFmSEBxxxvCXyquSPtqVJ
Contributor
Coverage Report for react-coverage (./react)
File Coverage
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
The extracted custom hook is missing the required React Compiler annotation directive.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Refactors idle-check classification to remove component coupling, reduce repeated parsing, and lazily render popover content.
Changes:
- Centralizes idle-check types and classification helpers.
- Passes parsed utilization data through presentational components.
- Adds 15 classification tests and updates Relay artifacts.
File summaries
| File | Description |
|---|---|
react/src/components/SessionDetailContent.tsx |
Updates the shared type import. |
react/src/components/ComputeSessionNodeItems/SessionReclamationStatusPopover.tsx |
Accepts parsed data and lazily renders content. |
react/src/components/ComputeSessionNodeItems/SessionReclamationStatusCell.tsx |
Separates Relay parsing from presentation. |
react/src/components/ComputeSessionNodeItems/SessionIdleChecks.tsx |
Reuses parsed utilization data. |
react/src/components/ComputeSessionNodeItems/idleChecks.ts |
Centralizes types and classification logic. |
react/src/components/ComputeSessionNodeItems/idleChecks.test.ts |
Tests classification behavior and boundaries. |
react/src/__generated__/SessionReclamationStatusPopoverFragment.graphql.ts |
Removes the obsolete generated fragment. |
react/src/__generated__/SessionReclamationStatusCellFragment.graphql.ts |
Removes the popover fragment spread. |
react/src/__generated__/SessionIdleChecksNodeFragment.graphql.ts |
Removes the status-cell fragment spread. |
react/src/__generated__/SessionDetailContentQuery.graphql.ts |
Regenerates the updated query. |
react/src/__generated__/resourceRegistrySessionQuery.graphql.ts |
Regenerates the updated query. |
react/src/__generated__/RecentlyCreatedSessionRefetchQuery.graphql.ts |
Regenerates the updated query. |
react/src/__generated__/PendingSessionNodeListQuery.graphql.ts |
Regenerates the updated query. |
react/src/__generated__/DashboardPageQuery.graphql.ts |
Regenerates the updated query. |
react/src/__generated__/ComputeSessionListPageQuery.graphql.ts |
Regenerates the updated query. |
react/src/__generated__/BAIComputeSessionNodeNotificationItemSubscription.graphql.ts |
Regenerates the updated subscription. |
react/src/__generated__/AstryxSessionProbeCasesQuery.graphql.ts |
Regenerates the updated probe query. |
react/src/__generated__/AdminDashboardPageQuery.graphql.ts |
Regenerates the updated query. |
react/src/__generated__/AdminComputeSessionListPageQuery.graphql.ts |
Regenerates the updated query. |
Review details
Files not reviewed (13)
- react/src/generated/AdminComputeSessionListPageQuery.graphql.ts: Generated file
- react/src/generated/AdminDashboardPageQuery.graphql.ts: Generated file
- react/src/generated/AstryxSessionProbeCasesQuery.graphql.ts: Generated file
- react/src/generated/BAIComputeSessionNodeNotificationItemSubscription.graphql.ts: Generated file
- react/src/generated/ComputeSessionListPageQuery.graphql.ts: Generated file
- react/src/generated/DashboardPageQuery.graphql.ts: Generated file
- react/src/generated/PendingSessionNodeListQuery.graphql.ts: Generated file
- react/src/generated/RecentlyCreatedSessionRefetchQuery.graphql.ts: Generated file
- react/src/generated/SessionDetailContentQuery.graphql.ts: Generated file
- react/src/generated/SessionIdleChecksNodeFragment.graphql.ts: Generated file
- react/src/generated/SessionReclamationStatusCellFragment.graphql.ts: Generated file
- react/src/generated/SessionReclamationStatusPopoverFragment.graphql.ts: Generated file
- react/src/generated/resourceRegistrySessionQuery.graphql.ts: Generated file
- Files reviewed: 6/19 changed files
- Comments generated: 1
- Review effort level: Balanced
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
Add the required 'use memo' React Compiler directive as the first statement of useReclamationColorMap. The repository runs React Compiler in annotation mode (.github/instructions/react.instructions.md), so the newly extracted hook was excluded from compiler memoization without it. Claude-Session: https://claude.ai/code/session_011RFmSEBxxxvCXyquSPtqVJ
Contributor
There was a problem hiding this comment.
🟢 Approval recommended
The refactor preserves classification semantics, removes redundant parsing and fragments, and includes focused regression tests.
Review details
Files not reviewed (13)
- react/src/generated/AdminComputeSessionListPageQuery.graphql.ts: Generated file
- react/src/generated/AdminDashboardPageQuery.graphql.ts: Generated file
- react/src/generated/AstryxSessionProbeCasesQuery.graphql.ts: Generated file
- react/src/generated/BAIComputeSessionNodeNotificationItemSubscription.graphql.ts: Generated file
- react/src/generated/ComputeSessionListPageQuery.graphql.ts: Generated file
- react/src/generated/DashboardPageQuery.graphql.ts: Generated file
- react/src/generated/PendingSessionNodeListQuery.graphql.ts: Generated file
- react/src/generated/RecentlyCreatedSessionRefetchQuery.graphql.ts: Generated file
- react/src/generated/SessionDetailContentQuery.graphql.ts: Generated file
- react/src/generated/SessionIdleChecksNodeFragment.graphql.ts: Generated file
- react/src/generated/SessionReclamationStatusCellFragment.graphql.ts: Generated file
- react/src/generated/SessionReclamationStatusPopoverFragment.graphql.ts: Generated file
- react/src/generated/resourceRegistrySessionQuery.graphql.ts: Generated file
- Files reviewed: 6/19 changed files
- Comments generated: 0 new
- Review effort level: Balanced
yomybaby
marked this pull request as ready for review
September 7, 2026 16:40
yomybaby
requested review from
nowgnuesLee
and removed request for
agatha197
September 7, 2026 23:50
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Resolves #8350 (FR-3351)
Follow-up refactor deferred from PR #8260 (FR-3318) review feedback. No behaviour change.
What changed
1. One home for the classification logic. The reclamation color logic lived in
SessionReclamationStatusPopover.tsxwhile theidle_checkspayload types lived inSessionIdleChecks.tsx, so the two sibling components imported each other (a type-onlycycle). Both now live in
react/src/components/ComputeSessionNodeItems/idleChecks.ts:IdleChecks/IdleCheckItem/UtilizationExtra,getUtilizationCheckerColor,getOverallReclamation, the severity ordering,RECLAMATION_LEGENDS,getIdleChecksTagColor, and theuseReclamationColorMaphook (it readst, so it staysa hook). Neither component imports the other any more.
2.
idle_checksis parsed once per boundary instead of three times for the samesession.
SessionReclamationStatusCellremains the Relay boundary for the session tableand hands the parsed utilization check to a new presentational
SessionReclamationStatus;SessionIdleChecksrenders that component directly from the payload it already parsed, soit no longer spreads
SessionReclamationStatusCellFragment. The popover takes the parsedUtilizationExtraas a prop, soSessionReclamationStatusPopoverFragmentis deleted.3. The popover body is built lazily. The content JSX moved into
ReclamationPopoverContent. AstryxHoverCardmounts itscontentlazily (useLayerrenders only a
<template>marker while closed), souseResourceSlotsDetails(), theper-resource rows and the legend rows now run when the card opens rather than for every
rendered session row.
Design decisions
UtilizationExtra.resourcesis typed asRecord<string, number[]>rather than theprevious fixed six keys (
cpu_util/mem/cuda_*/ipu_*): the manager builds the mapfrom the configured resource slots (
UtilizationResourceReportinidle.py), so thefixed shape did not describe the payload. Both consumers already treated it as an open
map.
getIdleChecksTagColormoved along with the rest — it is the same color classification,and moving it makes it unit-testable without importing a component.
SessionReclamationStatusstays inSessionReclamationStatusCell.tsxnext to its Relaywrapper rather than getting a file of its own.
Tests
react/src/components/ComputeSessionNodeItems/idleChecks.test.ts(15 cases) coveringthe color thresholds, the
and/orseverity pick, the "no measurement yet" filtering,and both branches of
getIdleChecksTagColor.pnpm --filter backend-ai-webui-react exec vitest run src/components/ComputeSessionNodeItems/idleChecks.test.ts→ 15 passed.pnpm --filter backend-ai-webui-react exec vitest run src/components/SessionDetailContent.test.tsx→ 3 passed.node scripts/migration-gates/astryx-token-gate.mjs --strict→ no new findings (only thepre-existing BUI ones).
Verification
bash scripts/verify.sh→Review notes
popover should be unchanged, and the popover should still open instantly (
delay={0}).SessionReclamationStatusfrom the already-parsed payload instead of the Relay cell; therow, tag colors and countdown should look identical.
__generated__churn is the removedSessionReclamationStatusPopoverFragmentand the two fragments that stopped spreading it/being spread.
Checklist: (if applicable)
https://claude.ai/code/session_011RFmSEBxxxvCXyquSPtqVJ