fix(realtime): survive signal outages and per-server identities
Peer recovery burned its whole retry budget while signaling was down, then dropped the tracker with no re-arm, so a peer stayed dead until an unrelated roster event healed it. Recovery now waits for a usable transport before spending an attempt. Initiator election also compared a home actor id against foreign roster ids, which is not antisymmetric across signal servers - both sides offered, or neither did. Election moves into `peer-role.rules` and compares ids only within one signal server's identity space.
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Deterministic WebRTC role election.
|
||||
*
|
||||
* Both ids must come from the **same signal server's identity space**. One human has a
|
||||
* separate account - and therefore a separate actor id - on every signal server they are
|
||||
* provisioned on, so comparing a home id against a foreign actor id is not antisymmetric:
|
||||
* each side compares its own home id against the other's foreign id, and both can elect
|
||||
* themselves initiator (glare) or neither can (no offer ever sent).
|
||||
*/
|
||||
export function shouldInitiatePeerConnection(
|
||||
localActorId: string | null | undefined,
|
||||
remoteActorId: string | null | undefined
|
||||
): boolean {
|
||||
const local = localActorId?.trim();
|
||||
const remote = remoteActorId?.trim();
|
||||
|
||||
if (!local || !remote)
|
||||
return false;
|
||||
|
||||
if (local === remote)
|
||||
return false;
|
||||
|
||||
return local < remote;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perfect-negotiation politeness, derived from the same election so the two can never
|
||||
* disagree: the elected initiator is the impolite side and keeps its offer, the other
|
||||
* side rolls back. Falls back to polite when the local actor id is unknown, so an
|
||||
* unidentified client yields instead of deadlocking the negotiation.
|
||||
*/
|
||||
export function isPoliteOnOfferCollision(
|
||||
localActorId: string | null | undefined,
|
||||
remoteActorId: string | null | undefined
|
||||
): boolean {
|
||||
return !shouldInitiatePeerConnection(localActorId, remoteActorId);
|
||||
}
|
||||
Reference in New Issue
Block a user