fix(core): align force-delete topology lock order to avoid observed deadlock in CI/CD#4015
fix(core): align force-delete topology lock order to avoid observed deadlock in CI/CD#4015pbreton wants to merge 1 commit into
Conversation
|
Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually. Contributors can view more details about this message here. |
WalkthroughThis PR clarifies force-delete lock-ordering comments in ChangesMachine force-delete lock ordering
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant SiteExplorer as Exploration Transaction
participant Postgres
participant ForceDelete as admin_force_delete_machine
participant Test as Regression Test
SiteExplorer->>Postgres: Lock machine_topologies row (FOR UPDATE)
Test->>ForceDelete: Trigger concurrent force-delete
ForceDelete->>Postgres: lock_by_machine_id (blocks on machine_topologies)
Test->>Postgres: wait_until_blocked_on_any(machine_topologies, cleanup_machine_by_id)
Test->>Postgres: Update explored_endpoints while delete blocked
SiteExplorer->>Postgres: Commit exploration transaction
Postgres-->>ForceDelete: Lock released
ForceDelete->>Postgres: Complete cleanup_machine_by_id
ForceDelete-->>Test: Managed host deleted
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
277951f to
7bdeb67
Compare
|
@coderabbitai full review |
✅ Action performedFull review finished. |
There was a problem hiding this comment.
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 `@crates/api-db/src/machine_topology.rs`:
- Around line 181-186: Replace the static query execution in the
machine-topology operation with a checked sqlx::query! or query_scalar! macro
while preserving its machine_id binding, transaction usage, and error mapping.
Apply the same checked-macro conversion to the three static query sites in
crates/api-core/src/tests/machine_admin_force_delete.rs at lines 471-475,
493-497, and 522-527; retain each query’s existing behavior and result handling.
🪄 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: CHILL
Plan: Enterprise
Run ID: a90b31b1-74a8-406d-b93c-5ee38bfe80e3
📒 Files selected for processing (3)
crates/api-core/src/handlers/machine.rscrates/api-core/src/tests/machine_admin_force_delete.rscrates/api-db/src/machine_topology.rs
kensimon
left a comment
There was a problem hiding this comment.
I know this is a draft, but before you go to far...
| ) -> DatabaseResult<()> { | ||
| const QUERY: &str = | ||
| "SELECT machine_id FROM machine_topologies WHERE machine_id = $1 FOR UPDATE"; | ||
| sqlx::query!( |
There was a problem hiding this comment.
Don't use the sqlx::query! macro, regardless of what @coderabbitai says. It's an interesting idea but we should either move everything to it or don't do it at all, it's out of scope to completely change the way we do queries (and require SQLX_OFFLINE and throw a bunch of static files in .sqlx) on a whim like this.
Delete all the .sqlx/* files and rollback the Dockerfiles and ci.yaml too.
There was a problem hiding this comment.
@kensimon, agreed. Introducing sqlx::query! and its offline-metadata/tooling requirements is out of scope for this targeted lock-ordering fix.
- Replace
sqlx::query!inlock_by_machine_idwith the existing runtime-query pattern (sqlx::query(QUERY).bind(machine_id)). - Remove every
.sqlx/*file added by this PR. - Revert this PR’s Dockerfile and
ci.yamlchanges that enabled or supported SQLx offline metadata. - Keep the topology lock behavior and regression test intact.
✏️ Learnings added
Learnt from: kensimon
Repo: NVIDIA/infra-controller PR: 4015
File: crates/api-db/src/machine_topology.rs:183-183
Timestamp: 2026-07-24T19:04:24.910Z
Learning: For NVIDIA/infra-controller Rust changes, do not introduce `sqlx::query!` macros, SQLX_OFFLINE, or generated `.sqlx` metadata as part of an isolated change. Continue using the repository’s existing runtime SQLx query APIs unless the project deliberately adopts compile-time SQLx queries through a separately scoped migration.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
- 📌 Commit the changes to this branch
There was a problem hiding this comment.
Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!
Signed-off-by: Patrice Breton <pbreton@nvidia.com>
8447526 to
3917a5c
Compare
|
@coderabbitai full review |
✅ Action performedFull review finished. |
Summary
We have observed multiple random CI/CD deadlock failures identical to https://github.com/NVIDIA/infra-controller/actions/runs/29973650808/job/89101241767?pr=3905. This PR tries to address it.
AdminForceDeleteMachine.Why
Site Explorer updates
machine_topologiesbeforeexplored_endpoints, while force-delete previously acquired those rows in the opposite order. When the two paths overlapped, PostgreSQL detected the cycle and abortedcleanup_machine_by_idwith40P01.Testing
cargo check --package carbide-api-dbcargo clippy --package carbide-api-db -- -D warningscargo fmt --allThe focused test was also attempted with:
cargo test --package carbide-api-core --no-default-features test_admin_force_delete_orders_topology_before_endpoint -- --nocapturecarbide-test-harness, a dev-dependency, depends back oncarbide-api-corewith default features and re-enableslinux-build. The resultingtss-esapi-sysbuild rejects the localaarch64-darwintarget, so this test still requires Linux CI.