Skip to content

Commit

Permalink
fix(ringing): Auto-Cancel outgoing calls (#1217)
Browse files Browse the repository at this point in the history
This PR fixes a bug in the `scheduleAutoDrop()` function that bailed out
from scheduling a cancellation timer when server-side-defined timeouts
remained the same after consecutive call settings updates.

Also, this PR aligns the implementation and relies only on
`auto_cancel_timeout_ms`. More context:
- https://getstream.slack.com/archives/C022N8JNQGZ/p1697701678593769

Fixes: #1215
  • Loading branch information
oliverlaz authored Dec 11, 2023
1 parent 8ac84eb commit c4d557b
Showing 1 changed file with 25 additions and 41 deletions.
66 changes: 25 additions & 41 deletions packages/client/src/Call.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,8 @@ import {
debounce,
filter,
map,
pairwise,
Subject,
takeWhile,
tap,
timer,
} from 'rxjs';
import { TrackSubscriptionDetails } from './gen/video/sfu/signal_rpc/signal';
Expand Down Expand Up @@ -1345,9 +1343,10 @@ export class Call {
};

/**
* Updates the list of video layers to publish.
*
* @internal
* @param enabledRids
* @returns
* @param enabledLayers the list of layers to enable.
*/
updatePublishQuality = async (enabledLayers: VideoLayerSetting[]) => {
return this.publisher?.updateVideoPublishQuality(enabledLayers);
Expand Down Expand Up @@ -1718,45 +1717,30 @@ export class Call {
>(`${this.streamClientBasePath}/members`, data);
};

/**
* Schedules an auto-drop timeout based on the call settings.
* Applicable only for ringing calls.
*/
private scheduleAutoDrop = () => {
if (this.dropTimeout) clearTimeout(this.dropTimeout);
const subscription = this.state.settings$
.pipe(
pairwise(),
tap(([prevSettings, currentSettings]) => {
if (!currentSettings || !this.clientStore.connectedUser) return;

const isOutgoingCall =
this.currentUserId === this.state.createdBy?.id;

const [prevTimeoutMs, timeoutMs] = isOutgoingCall
? [
prevSettings?.ring.auto_cancel_timeout_ms,
currentSettings.ring.auto_cancel_timeout_ms,
]
: [
prevSettings?.ring.incoming_call_timeout_ms,
currentSettings.ring.incoming_call_timeout_ms,
];
if (
typeof timeoutMs === 'undefined' ||
timeoutMs === prevTimeoutMs ||
timeoutMs === 0
)
return;

if (this.dropTimeout) clearTimeout(this.dropTimeout);
this.dropTimeout = setTimeout(() => this.leave(), timeoutMs);
}),
takeWhile(
() => !!this.clientStore.calls.find((call) => call.cid === this.cid),
),
)
.subscribe();
clearTimeout(this.dropTimeout);
this.leaveCallHooks.add(
createSubscription(this.state.settings$, (settings) => {
if (!settings) return;
// ignore if the call is not ringing
if (this.state.callingState !== CallingState.RINGING) return;

this.leaveCallHooks.add(() => {
!subscription.closed && subscription.unsubscribe();
});
const timeoutInMs = settings.ring.auto_cancel_timeout_ms;
// 0 means no auto-drop
if (timeoutInMs <= 0) return;

clearTimeout(this.dropTimeout);
this.dropTimeout = setTimeout(() => {
this.leave().catch((err) => {
this.logger('error', 'Failed to drop call', err);
});
}, timeoutInMs);
}),
);
};

/**
Expand Down

0 comments on commit c4d557b

Please sign in to comment.