mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-08-09 16:14:40 +00:00
Replace the blunt global concurrency number with per-relay back-pressure. Every relay starts generous (100 concurrent subscriptions) and is demoted down a ladder (100 -> 20 -> 10) only when it complains about concurrency — a CLOSED rate-limited, or a NOTICE like "too many concurrent REQs" / "too many subscriptions" / "burst exhausted". Well-behaved relays keep the full cap; only the busy hubs that push back get throttled, and only as far as they keep pushing. AdaptiveRelayLimiter registers as a RelayConnectionListener so demotions are driven straight off the same NOTICE/CLOSED frames RelayDiagnostics already observes, keyed by relay.url. Context.drain gains a gatePerRelay path that opens one subscription per relay, each held behind that relay's gate, so our concurrent subs on it never exceed its current cap. The gate is a fair FIFO bounded semaphore whose limit can only be lowered; shrinking below the in-use count admits no new subs until enough finish, so concurrency converges down to the new cap. Because a hot relay can no longer be flooded, the global content-drain fan-out is raised (18 -> 48) to crawl the many well-behaved relays faster. The crawl emits a relay_throttling summary (which relays were capped, and to what) alongside relay_feedback.