Skip to content

Throttle the contested-join operator notice to prevent log-flood on retry loops #14

Description

@obeone

Context

Follow-up from #13 (duplicate-join detection). Rated Low by the review — not blocking, tracked here.

When a join collides with a live peer, HubState.register returns CONTESTED and calls _announce_system(...) to surface a ⚠️ notice in the operator console (a UI feed event + an append to the bounded message log).

Problem

This path has no rate limit (unlike /send, which is gated by a TokenBucket). A buggy or hostile peer retrying POST /register in a tight loop under a name held by a live listener would:

  • flood the operator feed with ⚠️ ... duplicate refused notices, and
  • evict real history from the bounded deque(maxlen=500) message log.

So a single misbehaving client can wipe the recent-message buffer just by hammering register.

Proposed fix

Throttle (or de-duplicate) the contested notice per project: remember the last time a CONTESTED notice fired for a given project name and suppress repeats within a short window (e.g. a few seconds). Clear that bookkeeping when the peer is dropped (_drop) so it doesn't leak.

Keep it lightweight — this is purely a log/feed hygiene guard, not a security boundary.

Acceptance

  • Repeated contested registers for the same name within the window produce at most one operator notice.
  • The recent-message log is no longer floodable via /register.
  • Per-project throttle state is cleaned up on peer drop (no unbounded growth).

Pointers

  • src/caucus/state.pyHubState.register (CONTESTED branch), _announce_system, _drop
  • Compare with the existing TokenBucket rate limiting on the /send path

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