Skip to content

[state] Log pending-buffer evictions instead of silently discarding #123

@intendednull

Description

@intendednull

Parent: #108

Problem

crates/state/src/sync.rs:177-186:

pub fn buffer_for_prev(&mut self, prev_hash: EventHash, event: Event) {
    self.waiting_on_prev
        .entry(prev_hash)
        .or_default()
        .push(event);
    self.cached_count += 1;
    if let Some(limit) = self.max_pending {
        self.evict_to(limit);
    }
}

evict_to returns the number of evicted events — buffer_for_prev calls it and discards the return value. Nothing logs when pending events are dropped under capacity pressure. A gap in the DAG chain can be silently lost.

Fix

Capture the return value and log it:

if let Some(limit) = self.max_pending {
    let evicted = self.evict_to(limit);
    if evicted > 0 {
        tracing::warn!(
            evicted,
            buffer_size = self.cached_count,
            "pending buffer at capacity; dropped oldest events"
        );
    }
}

Optional follow-up: consider returning the evicted events from buffer_for_prev so the sync layer can re-request them later. That's larger and can be a separate issue.

Test

Add a test that inserts more events than max_pending, then asserts:

  1. The tracing span emits a warning. (Use tracing-test or a custom subscriber.)
  2. cached_count matches the cap.
  3. evicted > 0 is returned if you change the return type.

Note

The BTreeMap::keys().next() eviction order is already deterministic (this was flagged by the review agent but is a false positive — BTreeMap iterates in sorted key order). No change needed there.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions