Skip to content

feat: Limit the rate at which a conference adds endpoints to a bridge - #1298

Merged
bgrozev merged 1 commit into
masterfrom
bridge-spreading-rate-trigger
Aug 6, 2026
Merged

feat: Limit the rate at which a conference adds endpoints to a bridge#1298
bgrozev merged 1 commit into
masterfrom
bridge-spreading-rate-trigger

Conversation

@bgrozev

@bgrozev bgrozev commented Aug 6, 2026

Copy link
Copy Markdown
Member

Adds an optional per-(bridge, conference) limit on the rate at which a conference adds endpoints to a bridge: jicofo.bridge.max-bridge-participants-per-interval (default -1, i.e. disabled) over jicofo.bridge.max-bridge-participants-interval (default 1 minute). A suggested production value is 30.

Why

A bridge reports its stress level via presence only every 5-10 seconds. During a burst of joins the reported stress, and therefore correctedStress, is stale by construction, and selection keeps assigning to the same bridge long after it is full. Observed in production: a conference added 92 endpoints in 31 seconds, 58 of them landing on a single bridge which reached a real stress of 1.1, while 9-11 operational bridges in the same pool stayed below 0.05 stress. The logged stress for the overloaded bridge stayed frozen at 0.008 across ~15 consecutive selection decisions.

Rate is a better discriminator than a count:

  • A conference which grows to 30 endpoints on a bridge slowly is fine, the stress feedback has caught up and the existing logic works.
  • Many small conferences sharing a bridge each have a low rate of their own, so the limit never fires for them.

How

  • The rate is tracked with a RateTracker on Colibri2Session, which is exactly one object per (conference, bridge), so its lifecycle needs no extra bookkeeping: it is created with the session and dies with it (conference expiry, last endpoint leaving the bridge, bridge removal).
  • It reaches selection as a new field on ConferenceBridgeProperties, and is checked in the private merged Bridge.isOverloaded(conferenceBridges) next to hasMaxParticipantsInConference, so every selection strategy inherits it.
  • The check reads only conferenceBridges and config, never Bridge, so correctedStress, the bare Bridge.isOverloaded, bridge sorting, hasNonOverloadedBridge() and load redistribution are unchanged. Behavior for other conferences is unaffected.
  • The last-resort tier (leastLoadedNotMaxedAlreadyInConference) intentionally does not honor the limit. It exists to return some bridge rather than fail an allocation, and the limit is a spreading heuristic, not a capacity limit.
  • max-bridge-participants stays in effect as the hard cap.
  • A bridge hitting the limit is logged and counted (bridge_selection_rate_limited), and the per-session count is exposed in the debug state.

Also fixes a fidelity gap in TestColibri2Server, which ignored the conference-level expire flag and so never let a bridge be re-used after its session was torn down.

Adds an optional per-(bridge, conference) limit on the number of endpoints
that a conference may add to a bridge within an interval
(max-bridge-participants-per-interval, disabled by default).

A bridge reports its stress level only every 5-10 seconds, so during a burst
of joins the reported stress (and therefore correctedStress) is stale by
construction, and selection keeps using the same bridge long after it is full.
Limiting the rate of growth bounds the overshoot, while leaving a conference
which grows slowly, and many small conferences sharing a bridge, unaffected.

The rate is tracked per colibri2 session, so its lifecycle matches the
(conference, bridge) pair exactly. It is exposed to selection via
ConferenceBridgeProperties and checked alongside max-bridge-participants, so
neither correctedStress nor Bridge.isOverloaded change, and the behavior for
other conferences is unaffected.
jitsi-ci Bot pushed a commit to jitsi/jitsi-pr-tests-pages that referenced this pull request Aug 6, 2026
@codecov

codecov Bot commented Aug 6, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.43590% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 50.98%. Comparing base (b64b530) to head (41f2e96).

Files with missing lines Patch % Lines
...i/jicofo/bridge/colibri/ColibriV2SessionManager.kt 80.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1298      +/-   ##
==========================================
+ Coverage   50.47%   50.98%   +0.50%     
==========================================
  Files         131      131              
  Lines        8251     8285      +34     
  Branches     1261     1268       +7     
==========================================
+ Hits         4165     4224      +59     
+ Misses       3493     3465      -28     
- Partials      593      596       +3     
Files with missing lines Coverage Δ
...ain/kotlin/org/jitsi/jicofo/bridge/BridgeConfig.kt 92.38% <100.00%> (+0.30%) ⬆️
...in/kotlin/org/jitsi/jicofo/bridge/BridgeMetrics.kt 95.00% <100.00%> (+0.88%) ⬆️
...org/jitsi/jicofo/bridge/BridgeSelectionStrategy.kt 77.57% <100.00%> (+9.82%) ⬆️
...n/kotlin/org/jitsi/jicofo/bridge/BridgeSelector.kt 67.76% <100.00%> (+0.26%) ⬆️
...org/jitsi/jicofo/bridge/colibri/Colibri2Session.kt 69.28% <100.00%> (+4.26%) ⬆️
...i/jicofo/bridge/colibri/ColibriV2SessionManager.kt 57.54% <80.00%> (+0.43%) ⬆️

... and 3 files with indirect coverage changes


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update b64b530...41f2e96. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@bgrozev
bgrozev merged commit 076a4c7 into master Aug 6, 2026
6 checks passed
@bgrozev
bgrozev deleted the bridge-spreading-rate-trigger branch August 6, 2026 19:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants