Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Mark bridge unhealthy based on restart requests from endpoints #1210

Merged
merged 13 commits into from
Feb 21, 2025
Merged
15 changes: 12 additions & 3 deletions jicofo-selector/src/main/kotlin/org/jitsi/jicofo/bridge/Bridge.kt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import org.jxmpp.jid.Jid
import java.time.Clock
import java.time.Duration
import java.time.Instant
import java.util.concurrent.atomic.AtomicInteger
import org.jitsi.jicofo.bridge.BridgeConfig.Companion.config as config

/**
Expand Down Expand Up @@ -57,6 +58,9 @@ class Bridge @JvmOverloads internal constructor(
clock
)

/** Number of endpoints currently allocated on this bridge by this jicofo instance. */
val endpoints = AtomicInteger(0)

/**
* The last report stress level
*/
Expand Down Expand Up @@ -237,11 +241,15 @@ class Bridge @JvmOverloads internal constructor(
return compare(this, other)
}

/**
* Notifies this [Bridge] that it was used for a new endpoint.
*/
/** Notifies this [Bridge] that it was used for a new endpoint. */
fun endpointAdded() {
newEndpointsRate.update(1)
endpoints.incrementAndGet()
}

fun endpointRemoved() = endpointsRemoved(1)
fun endpointsRemoved(count: Int) {
endpoints.addAndGet(-count);
}

/**
Expand Down Expand Up @@ -292,6 +300,7 @@ class Bridge @JvmOverloads internal constructor(
val debugState: OrderedJsonObject
get() = OrderedJsonObject().apply {
this["drain"] = isDraining
this["endpoints"] = endpoints.get()
this["graceful-shutdown"] = isInGracefulShutdown
this["healthy"] = isHealthy
this["operational"] = isOperational
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,10 +214,7 @@ class BridgeSelector @JvmOverloads constructor(
conferenceBridges,
participantProperties,
OctoConfig.config.enabled
).also {
// The bridge was selected for an endpoint, increment its counter.
it?.endpointAdded()
}
)
}

val stats: JSONObject
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ class ColibriV2SessionManager(
logger.info("Expiring.")
sessions.values.forEach { session ->
logger.debug { "Expiring $session" }
session.bridge.endpointsRemoved(getSessionParticipants(session).size)
session.expire()
}
sessions.clear()
Expand All @@ -134,6 +135,7 @@ class ColibriV2SessionManager(

private fun removeSession(session: Colibri2Session): Set<ParticipantInfo> {
val participants = getSessionParticipants(session)
session.bridge.endpointsRemoved(participants.size)
session.expire()
removeNode(session, ::repairMesh)
sessions.remove(session.relayId)
Expand Down Expand Up @@ -162,6 +164,7 @@ class ColibriV2SessionManager(
sessionRemoved = true
} else {
session.expire(sessionParticipantsToRemove)
session.bridge.endpointRemoved()
sessionParticipantsToRemove.forEach { remove(it) }
participantsRemoved.addAll(sessionParticipantsToRemove)

Expand Down Expand Up @@ -334,6 +337,7 @@ class ColibriV2SessionManager(
)
}
participantInfo = ParticipantInfo(participant, session)
session.bridge.endpointAdded()
stanzaCollector = session.sendAllocationRequest(participantInfo)
add(participantInfo)
if (created) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class BridgeSelectorTest : ShouldSpec() {
val bridge = bridgeSelector.addJvbAddress(jid1).apply { setStats() }
bridge.stress shouldBe 0
bridgeSelector.selectBridge()
bridge.endpointAdded()
// The stress should increase because it was recently selected.
bridge.stress shouldNotBe 0
}
Expand Down