fix(server): scope accept-rollback terminal to the acceptor only
Code-review catch: the Path-2 accept-rollback previously emitted
dm_call_undeliverable { terminal: true } via sendToFederatedCallUsers,
which broadcasts to every ringedUserIds entry. In a group DM this
would prematurely tear down non-accepting ringees whose own accept /
reject / timeout paths should govern their state. Switch to
sendToUser(acceptorId) so only the acting user gets the terminal
signal. Reorder the clearFederatedCall to happen before the emit so a
concurrent end-handler sees a cleared entry (clearFederatedCall is
idempotent). Spec updated, test extended to assert the scoping with a
two-ringee group-DM fixture.
This commit is contained in:
@@ -1563,7 +1563,12 @@ async function handleDmCallAccept(event: Record<string, unknown>, userId: string
|
||||
if (!result.ok) {
|
||||
console.error(`[federation] dm_call_accept relay to ${fedCall.federatedCallHost} failed (${result.reason}): ${result.error}`);
|
||||
const failure = buildFailureFromResult(result, fedCall.federatedCallHost, db);
|
||||
connectionManager.sendToFederatedCallUsers(fedCall.federatedId, {
|
||||
// Clear first so a concurrent end-handler sees a cleared entry (idempotent).
|
||||
connectionManager.clearFederatedCall(fedCall.federatedId);
|
||||
// Terminal targets ONLY the acceptor — other ringed users (group DM) didn't
|
||||
// accept and should stay in their ring state; their own dm_call_end / timeout
|
||||
// paths govern their teardown.
|
||||
connectionManager.sendToUser(userId, {
|
||||
type: 'dm_call_undeliverable',
|
||||
dmChannelId: fedCall.dmChannelId,
|
||||
federatedCallId: fedCall.federatedId,
|
||||
@@ -1571,7 +1576,6 @@ async function handleDmCallAccept(event: Record<string, unknown>, userId: string
|
||||
phase: 'accept',
|
||||
failures: [failure],
|
||||
});
|
||||
connectionManager.clearFederatedCall(fedCall.federatedId);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user