Skip to content

v2.4.32

Choose a tag to compare

@datapoke datapoke released this 05 May 18:07
· 16 commits to trunk since this release

Fixed

  • Aggregator: SSE slot TTL / heartbeat asymmetry caused 429 "Maximum concurrent SSE streams reached" rate-limiting on spokes after StreamMerger restarts. The browser side runs 5s heartbeat against a 10s slot TTL (2x headroom — slots free within ~5s of disconnect); the aggregator side ran 15s heartbeat against a 300s TTL (20x headroom — slots stayed reserved up to ~285s after a worker exited). With MAX_SSE_SLOTS = 10 per user_id:ip_hash, a few rapid restart cycles exhausted the pool. Brought SLOT_TTL_AGGREGATOR to 30s (same 2x ratio as browsers) and updated the constant's comment to explain the relationship.
  • Aggregator: SSE slots are now scoped per-partition instead of sharing the global MAX_SSE_SLOTS = 10 pool with browser tabs and other partitions. Memcached::{acquire,check,touch,release}_sse_slot() and sse_slot_key() accept an optional int $partition (default -1 preserves the browser-style shared pool). SSEControllerBase::start_sse_stream() threads the partition from $connected_data into the slot acquisition when is_aggregator=true, and stores it for matching releases/checks. The firehose/heartbeat endpoint accepts a partition arg, and StreamMerger::maybe_send_heartbeat() includes it in the POST so each partition refreshes its own keyed slot. Added a regression test covering pool-independence and partition-scoped lookup.