Skip to content

perf(instance-address): persist allocated addresses in one INSERT under the lock#3397

Open
chet wants to merge 1 commit into
NVIDIA:mainfrom
chet:gh-issue-3215
Open

perf(instance-address): persist allocated addresses in one INSERT under the lock#3397
chet wants to merge 1 commit into
NVIDIA:mainfrom
chet:gh-issue-3215

Conversation

@chet

@chet chet commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Instance-address allocation holds an ACCESS EXCLUSIVE lock on instance_addresses while it writes the newly assigned addresses -- one INSERT at a time, up to ~18 sequential statements for a dual-stack host with nine interfaces, serializing concurrent allocations across every round-trip.

allocate now gathers every interface's addresses and writes them with a single multi-row push_values INSERT (chunked well above any real allocation size), so the write side of the lock window is one statement regardless of address count:

  • insert_instance_addresses -- one INSERT for the whole set, execute() instead of fetch_all() (the INSERT returns nothing). Rows are api-model's InstanceAddress (its prefix slot was already reserved there), now shared by the table's readers and this write.
  • Column set, types, and hostname derivation are unchanged; a query-count test pins N addresses to exactly one statement, plus per-field persistence and empty-input guards.
  • Also restores the perf(db): count rows in the database instead of fetching them to count #3387 review fixes its merge predated: the drain predicate's second-EXISTS-arm regression test, the redundant ::uuid cast removal, and the drain log's segment_id key.

This supports #3215

@chet chet requested a review from a team as a code owner July 11, 2026 01:33
@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 481fb939-83ec-4407-ab35-1202033bc438

📥 Commits

Reviewing files that changed from the base of the PR and between 568c589 and b165ec5.

⛔ Files ignored due to path filters (2)
  • lint-carbide.log is excluded by !**/*.log
  • lint-clippy.log is excluded by !**/*.log
📒 Files selected for processing (3)
  • crates/api-db/src/instance_address.rs
  • crates/api-model/src/instance_address.rs
  • crates/network-segment-controller/src/handler.rs

Summary by CodeRabbit

  • Bug Fixes

    • Segment deletion now correctly detects allocations that exist only as instance addresses, preventing premature cleanup.
    • Instance address records now retain CIDR prefixes and hostnames for more accurate network and DNS information.
    • Improved segment-related logging provides more accurate identifiers during deletion.
  • Performance

    • Address allocation persistence now uses batched database writes, improving efficiency when assigning multiple addresses.

Walkthrough

Instance address allocation now stores prefix and hostname data, batches database inserts within bind limits, and checks allocations across both relevant tables. Database tests cover persistence and empty inputs. Segment drain logging now uses the handler’s segment identifier.

Changes

Instance address batching

Layer / File(s) Summary
Address contract and persistence
crates/api-model/src/instance_address.rs, crates/api-db/src/instance_address.rs
InstanceAddress now includes prefix and nullable hostname; allocation collects rows and persists them with parameter-bounded multi-row inserts, with tests covering statement counts, stored fields, and empty input.
Allocation predicate coverage
crates/api-db/src/instance_address.rs
segment_has_allocations checks both machine_interfaces and instance_addresses, with coverage for instance-address-only allocations.

Segment drain logging

Layer / File(s) Summary
Segment log field
crates/network-segment-controller/src/handler.rs
The allocated-IP drain log records the segment_id parameter.

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

Sequence Diagram(s)

sequenceDiagram
  participant Allocation
  participant BatchInsert
  participant Database
  Allocation->>BatchInsert: Accumulated instance addresses
  BatchInsert->>Database: Bounded multi-row INSERT
  Database-->>BatchInsert: Persisted rows
  BatchInsert-->>Allocation: Insert completion
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: batching instance-address persistence into one INSERT under the lock.
Description check ✅ Passed The description is clearly related to the changeset and matches the performance and test updates described in the summary.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@chet

chet commented Jul 11, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai full_review, thanks!

@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

@chet, sounds good — I'll redo the full review of all changes in this PR now.

✅ Action performed

Full review finished.

@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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
crates/api-db/src/instance_address.rs (1)

456-508: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Persist overlay allocations before the next interface is processed

When two interfaces in the same request target the same overlay segment, the second IpAllocator is created before the first allocation has been written to instance_addresses, so it can hand out a duplicate IP. The exclusive lock does not prevent that; the resolver only sees rows already persisted. Either write each overlay row before continuing, or seed the next resolver with the addresses accumulated so far.

🤖 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/instance_address.rs` around lines 456 - 508, Ensure
allocations for multiple interfaces targeting the same overlay segment account
for addresses assigned earlier in the request. Update the allocation flow around
IpAllocator and UsedOverlayNetworkIpResolver so each subsequent resolver
includes accumulated rows from the current transaction, or persist each overlay
allocation before processing the next interface; retain the final batch insert
behavior where possible and prevent duplicate IP assignment.
🤖 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.

Outside diff comments:
In `@crates/api-db/src/instance_address.rs`:
- Around line 456-508: Ensure allocations for multiple interfaces targeting the
same overlay segment account for addresses assigned earlier in the request.
Update the allocation flow around IpAllocator and UsedOverlayNetworkIpResolver
so each subsequent resolver includes accumulated rows from the current
transaction, or persist each overlay allocation before processing the next
interface; retain the final batch insert behavior where possible and prevent
duplicate IP assignment.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: edae9a07-a83e-400a-a9a8-b24b10005f8c

📥 Commits

Reviewing files that changed from the base of the PR and between 83ea2c4 and dbea955.

📒 Files selected for processing (2)
  • crates/api-db/src/instance_address.rs
  • crates/network-segment-controller/src/handler.rs

@github-actions

Copy link
Copy Markdown

🔍 Container Scan Summary

Service Total Critical High Medium Low Other
boot-artifacts-aarch64 3 0 0 3 0 0
boot-artifacts-x86_64 3 0 0 3 0 0
forge-admin-cli-x86_64 271 13 34 91 7 126
machine-validation-runner 804 40 237 296 36 195
machine_validation 804 40 237 296 36 195
machine_validation-aarch64 804 40 237 296 36 195
nvmetal-carbide 804 40 237 296 36 195
TOTAL 3493 173 982 1281 151 906

Per-CVE detail lives in the per-service grype-* artifacts (JSON + SARIF). Severity counts only — no CVE IDs published here.

…er the lock

Instance-address allocation holds an `ACCESS EXCLUSIVE` lock on `instance_addresses` while it writes the newly assigned addresses. It inserted them one row at a time -- up to ~18 sequential INSERTs for a host with nine interfaces and dual-stack -- so the lock stayed held across every round-trip and serialized concurrent allocations for that whole span.

`allocate` now gathers every interface's addresses and writes them with a single multi-row INSERT, so the write side of the lock window is one statement regardless of address count. The write also uses `execute()` rather than `fetch_all()` (the INSERT returns nothing).

- Add `insert_instance_addresses`: one `push_values` INSERT for the set.
- Rows are `api-model`'s `InstanceAddress` (its `prefix` slot was already reserved there), now shared by the table's readers and this batched write.
- Gather rows across all interfaces, write once after the loops.
- A query-count test guards it: N addresses persist in one statement.
- Restore the NVIDIA#3387 review fixes its merge predated: the drain predicate's second-`EXISTS`-arm regression test, the redundant `::uuid` cast removal, and the drain log's `segment_id` key.

Column set, types, and hostname derivation are unchanged.

This supports NVIDIA#3215

Signed-off-by: Chet Nichols III <chetn@nvidia.com>
@chet

chet commented Jul 11, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai full_review, thanks!

@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

@chet, got it — kicking off another full review of all changes in this PR now.

✅ Action performed

Full review finished.

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