Skip to content

draft - #4653

Open
spydaNVIDIA wants to merge 1 commit into
NVIDIA:mainfrom
spydaNVIDIA:history
Open

draft#4653
spydaNVIDIA wants to merge 1 commit into
NVIDIA:mainfrom
spydaNVIDIA:history

Conversation

@spydaNVIDIA

Copy link
Copy Markdown
Contributor

Related issues

Type of Change

  • Add - New feature or capability
  • Change - Changes in existing functionality
  • Fix - Bug fixes
  • Remove - Removed features or deprecated functionality
  • Internal - Internal changes (refactoring, tests, docs, etc.)

Breaking Changes

  • This PR contains breaking changes

Testing

  • Unit tests added/updated
  • Integration tests added/updated
  • Manual testing performed
  • No testing required (docs, internal refactor, etc.)

Additional Notes

@spydaNVIDIA
spydaNVIDIA requested a review from a team as a code owner August 6, 2026 06:09
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Summary by CodeRabbit

  • New Features

    • Added health-history tracking for switches, including aggregate health snapshots.
    • Health records now avoid duplicate unchanged observations and retain the newest 250 entries per switch.
    • Added support for updating switch identifiers associated with historical health records.
  • Bug Fixes

    • Health aggregation is now calculated consistently before metrics and history recording.

Walkthrough

The PR adds switch health-history storage with deduplication and 250-record retention. The switch controller computes aggregate health once, records metrics, and queues deferred persistence through a PostgreSQL write operation. Integration tests cover insertion, retention, deduplication, and object-ID updates.

Changes

Switch health history

Layer / File(s) Summary
Health-history storage and database behavior
crates/api-db/migrations/20260805120000_switch_health_history.sql, crates/api-db/src/health_history.rs
Adds the switch_health_history table, deduplicated persistence, object-ID updates, 250-row retention, and integration tests for the switch history behavior.
Controller aggregation and deferred persistence
crates/switch-controller/Cargo.toml, crates/switch-controller/src/lib.rs, crates/switch-controller/src/write_ops.rs, crates/switch-controller/src/handler.rs
Computes one aggregate health report, records metrics with that report, and queues PersistSwitchHealthHistory for transactional database persistence.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant handle_object_state
  participant record_metrics
  participant PersistSwitchHealthHistory
  participant PostgreSQL

  handle_object_state->>handle_object_state: Aggregate switch health once
  handle_object_state->>record_metrics: Pass aggregate report
  handle_object_state->>PersistSwitchHealthHistory: Queue switch ID and report
  PersistSwitchHealthHistory->>PostgreSQL: Persist deduplicated history row
  PostgreSQL->>PostgreSQL: Retain newest 250 rows per switch
Loading
🚥 Pre-merge checks | ✅ 2 | ❌ 3

❌ Failed checks (1 warning, 2 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title "draft" is too vague to identify the switch health history change. Replace "draft" with a concise title that describes persisting switch health history.
Description check ❓ Inconclusive The description contains only the default template and provides no meaningful details about the switch health history change. Complete the template with the purpose, implementation summary, related issues, and testing details.
✅ Passed checks (2 passed)
Check name Status Explanation
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.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@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: 2

🧹 Nitpick comments (2)
crates/switch-controller/src/handler.rs (1)

75-78: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Move the aggregate report into the deferred write.

record_metrics borrows aggregate_health before the history write. Change record_health_history to take ownership and move the report into PersistSwitchHealthHistory. This removes one full clone per state-handler iteration.

🤖 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 `@crates/switch-controller/src/handler.rs` around lines 75 - 78, Update
record_health_history to take ownership of aggregate_health and move it directly
into PersistSwitchHealthHistory, rather than cloning it. Adjust the
state-handler flow so record_metrics borrows the report before the deferred
history write while preserving existing behavior.

Source: Coding guidelines

crates/switch-controller/src/lib.rs (1)

39-39: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Restrict the write-operation API to this crate.

PersistSwitchHealthHistory has no external callers. Change write_ops and its struct fields to pub(crate) so handler.rs can construct it without exposing this implementation detail.

🤖 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 `@crates/switch-controller/src/lib.rs` at line 39, Restrict the write-operation
API to crate scope: change the write_ops module declaration in
crates/switch-controller/src/lib.rs:39-39 to pub(crate), and change the fields
of PersistSwitchHealthHistory in crates/switch-controller/src/write_ops.rs:32-35
to pub(crate) so handler.rs can construct it without exposing the implementation
publicly.

Source: Coding guidelines

🤖 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 `@crates/api-db/migrations/20260805120000_switch_health_history.sql`:
- Around line 16-28: Ensure the 250-row retention limit is enforced when
histories are merged through object-ID updates, not only after inserts. In
crates/api-db/migrations/20260805120000_switch_health_history.sql lines 16-28,
extend the retention trigger to cover object_id updates if retaining
trigger-based enforcement; in crates/api-db/src/health_history.rs lines 198-200,
delete excess rows for new_object_id within the same update_object_ids
transaction. Add a test covering the merge of two histories that each contain
250 records.

In `@crates/api-db/src/health_history.rs`:
- Around line 160-174: Make the HealthHistoryTableId::Switch persistence query
atomically deduplicate identical reports per object_id, using per-object
serialization or a database uniqueness constraint with an atomic insert rather
than the current NOT EXISTS check. Add an integration test using two database
connections that concurrently submit the same health report and verifies only
one row is inserted.

---

Nitpick comments:
In `@crates/switch-controller/src/handler.rs`:
- Around line 75-78: Update record_health_history to take ownership of
aggregate_health and move it directly into PersistSwitchHealthHistory, rather
than cloning it. Adjust the state-handler flow so record_metrics borrows the
report before the deferred history write while preserving existing behavior.

In `@crates/switch-controller/src/lib.rs`:
- Line 39: Restrict the write-operation API to crate scope: change the write_ops
module declaration in crates/switch-controller/src/lib.rs:39-39 to pub(crate),
and change the fields of PersistSwitchHealthHistory in
crates/switch-controller/src/write_ops.rs:32-35 to pub(crate) so handler.rs can
construct it without exposing the implementation publicly.
🪄 Autofix

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: CHILL

Plan: Enterprise

Run ID: add99e78-76e7-451c-915c-c039b518cf11

📥 Commits

Reviewing files that changed from the base of the PR and between 4f0e11f and 95aa794.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (6)
  • crates/api-db/migrations/20260805120000_switch_health_history.sql
  • crates/api-db/src/health_history.rs
  • crates/switch-controller/Cargo.toml
  • crates/switch-controller/src/handler.rs
  • crates/switch-controller/src/lib.rs
  • crates/switch-controller/src/write_ops.rs

Comment on lines +16 to +28
CREATE OR REPLACE FUNCTION switch_health_history_keep_limit()
RETURNS TRIGGER AS
$body$
BEGIN
DELETE FROM switch_health_history WHERE object_id=NEW.object_id AND id NOT IN (SELECT id from switch_health_history where object_id=NEW.object_id ORDER BY id DESC LIMIT 250);
RETURN NULL;
END;
$body$
LANGUAGE plpgsql;

CREATE TRIGGER t_switch_health_history_keep_limit
AFTER INSERT ON switch_health_history
FOR EACH ROW EXECUTE PROCEDURE switch_health_history_keep_limit();

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.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Apply retention after object-ID updates.

The trigger runs only after INSERT. update_object_ids changes object_id without invoking the trigger. If both object IDs have 250 records, one rename can leave 500 records under the new ID.

Enforce the 250-record limit in the object-ID update transaction, or extend retention to object-ID updates. Add a test that merges two full histories.

  • crates/api-db/migrations/20260805120000_switch_health_history.sql#L16-L28: retain rows after an object_id change if trigger-based enforcement is kept.
  • crates/api-db/src/health_history.rs#L198-L200: delete excess rows for new_object_id after the rename within the same transaction.
📍 Affects 2 files
  • crates/api-db/migrations/20260805120000_switch_health_history.sql#L16-L28 (this comment)
  • crates/api-db/src/health_history.rs#L198-L200
🤖 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 `@crates/api-db/migrations/20260805120000_switch_health_history.sql` around
lines 16 - 28, Ensure the 250-row retention limit is enforced when histories are
merged through object-ID updates, not only after inserts. In
crates/api-db/migrations/20260805120000_switch_health_history.sql lines 16-28,
extend the retention trigger to cover object_id updates if retaining
trigger-based enforcement; in crates/api-db/src/health_history.rs lines 198-200,
delete excess rows for new_object_id within the same update_object_ids
transaction. Add a test covering the merge of two histories that each contain
250 records.

Comment on lines +160 to +174
HealthHistoryTableId::Switch => "WITH new_history_record as(
SELECT $1 as object_id,
$2::jsonb as health,
$3 as health_hash,
$4 as time
),
last_history_record as(
SELECT health_hash FROM switch_health_history
WHERE object_id = $1
ORDER BY id DESC
LIMIT 1
)
INSERT INTO switch_health_history (object_id, health, health_hash, time)
SELECT * FROM new_history_record
WHERE NOT EXISTS (SELECT health_hash FROM last_history_record WHERE last_history_record.health_hash = new_history_record.health_hash);",

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.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect persistence call paths and any existing serialization of switch writes.
rg -n -C5 '\bPersistSwitchHealthHistory\b|\bhealth_history::persist\s*\(|\bDbWriteBatch\b|handle_object_state' \
  crates/switch-controller crates/state-controller crates/api-db

Repository: NVIDIA/infra-controller

Length of output: 22063


Make switch health deduplication atomic.

Concurrent transactions can both read the same latest hash and insert duplicate rows. Serialize persistence per object_id, or enforce deduplication with a database constraint and an atomic insert. Add a two-connection integration test for concurrent identical reports.

🤖 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 `@crates/api-db/src/health_history.rs` around lines 160 - 174, Make the
HealthHistoryTableId::Switch persistence query atomically deduplicate identical
reports per object_id, using per-object serialization or a database uniqueness
constraint with an atomic insert rather than the current NOT EXISTS check. Add
an integration test using two database connections that concurrently submit the
same health report and verifies only one row is inserted.

@wminckler

Copy link
Copy Markdown
Contributor

title is "draft" and description is empty

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.

2 participants