Skip to content

SimNode buffer delta capacity#1965

Draft
cursor[bot] wants to merge 3 commits intomasterfrom
cursor/simnode-buffer-delta-capacity-1254
Draft

SimNode buffer delta capacity#1965
cursor[bot] wants to merge 3 commits intomasterfrom
cursor/simnode-buffer-delta-capacity-1254

Conversation

@cursor
Copy link
Contributor

@cursor cursor bot commented Feb 12, 2026

node: Fix SimNode buffer_delta zero capacity edge case

Description

This PR fixes a bug in SimNode::buffer_delta where it mishandled the zero-capacity edge case, diverging from the production DeltaBuffer::push behavior.
Specifically, when buffer_capacity was 0, SimNode::buffer_delta would incorrectly add deltas to the buffer and fail to increment buffer_drops.

This change adds an explicit zero-capacity guard to SimNode::buffer_delta to match the production DeltaBuffer::push implementation. This ensures that deltas are immediately dropped and buffer_drops is incremented when capacity is zero, aligning the simulation with production behavior for accurate testing of delta buffer invariants.

Fixes bug 2e1fad8b-f396-4a24-89d0-15b1c51e48ad: SimNode buffer_delta mishandles zero capacity edge case.

Test plan

The existing cargo test suite was run. cargo check and cargo clippy passed, confirming syntactic correctness and no new warnings. The fix directly addresses the identified logic divergence, ensuring existing simulation tests now correctly reflect production behavior for zero-capacity buffers.

Documentation update

None. This is an internal simulation fix.


xilosada and others added 3 commits February 12, 2026 02:54
Add comprehensive simulation tests verifying delta buffering behavior
during state-based sync (Invariant I6: deltas arriving during sync
MUST be preserved and applied after sync completes).

Changes:
- Enhanced DeltaBuffer with FIFO eviction (oldest-first drop policy)
- Added drops counter and configurable capacity
- Integrated cancel_sync_session for proper error handling
- Added 7 simulation test scenarios covering:
  - Deltas buffered during active sync
  - Buffered deltas replayed on completion
  - Immediate application when idle
  - Buffer cleared on crash
  - Multiple deltas preserved in FIFO order
  - Convergence blocked while buffer non-empty
  - Complex snapshot sync with concurrent writes

All 176 sync_sim tests pass.
Addresses all review comments from PR #1959:

**Bug Fixes:**
- Fix zero capacity edge case in DeltaBuffer::push - now correctly
  drops incoming delta and returns its ID instead of phantom drops
- Change push() return type to Option<[u8; 32]> to return the evicted
  delta's ID (fixes misleading log message issue)
- Add record_write() metrics in SyncComplete replay loop for
  consistent observability

**Code Quality:**
- Remove dead code get_buffer_metrics() with #[allow(dead_code)]
- Add finish_sync() method on SimNode to atomically drain buffered
  ops, clear buffer, and reset sync state (prevents partial cleanup)
- Extract rate-limit duration as DELTA_BUFFER_DROP_WARNING_RATE_LIMIT_S
  constant

**Test Coverage:**
- Add test_zero_capacity_drops_immediately unit test
- Add test_buffer_overflow_fifo_eviction simulation test
- Add test_buffer_drops_accumulated simulation test
- Add buffer_drops metric to EffectMetrics

All 178 sync_sim tests pass, 7 delta_buffer unit tests pass.
Add explicit early-return guard for zero-capacity edge case in
SimNode::buffer_delta to match production DeltaBuffer::push behavior.

Previously, when buffer_capacity was 0:
- The condition '0 >= 0' was true, entering the eviction branch
- But first() returned None on the empty buffer
- The if-let block was skipped (buffer_drops not incremented)
- The push() call still executed, incorrectly adding the delta

Now, when buffer_capacity is 0:
- We immediately increment buffer_drops and return false
- The buffer remains empty (matching production behavior)
- The drop is properly counted
@cursor
Copy link
Contributor Author

cursor bot commented Feb 12, 2026

Cursor Agent can help with this pull request. Just @cursor in comments and I'll start working on changes in this branch.
Learn more about Cursor Agents

@github-actions
Copy link

Your PR title does not adhere to the Conventional Commits convention:

<type>(<scope>): <subject>

Common errors to avoid:

  1. The title must be in lower case.
  2. Allowed type values are: build, ci, docs, feat, fix, perf, refactor, test.

Copy link

@meroreviewer meroreviewer bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Code Reviewer

Reviewed by 3 agents | Quality score: 100% | Review time: 203.6s

💡 1 suggestions. See inline comments.


🤖 Generated by AI Code Reviewer | Review ID: review-f7e6a03f

///
/// Implements FIFO eviction when buffer is full. Returns `true` if added without
/// eviction, `false` if oldest delta was evicted.
/// eviction, `false` if oldest delta was evicted or dropped.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Consider adding explicit unit test for zero-capacity edge case

Since this bug was discovered in test infrastructure, adding a regression test specifically for buffer_delta with buffer_capacity == 0 would prevent future regressions.

Suggested fix:

Add a test like `#[test] fn buffer_delta_zero_capacity_drops_immediately() { let mut node = SimNode::with_buffer_capacity("n1", 0); assert!(!node.buffer_delta(DeltaId::ZERO)); assert_eq!(node.buffer_drops, 1); }`

Base automatically changed from feat/sync-delta-buffering-sim-i6 to master February 12, 2026 04:13
@github-actions
Copy link

This pull request has been automatically marked as stale. If this pull request is still relevant, please leave any comment (for example, "bump"), and we'll keep it open. We are sorry that we haven't been able to prioritize reviewing it yet. Your contribution is very much appreciated.

@github-actions github-actions bot added the Stale label Feb 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants