Skip to content

Commit 8395919

Browse files
authored
MatrixRTC: Fix running not representing what we need from isJoined in EC (#4752)
* Fix running != isJoined EC expects isJoined to represent if we should be in joined state or not. It does not correlate to what our actual state of the scheduler is. We used the scheduler running state before but on leave the running state will stay true until we successfully updated the room state. EC expects isJoined to immediately be false. This introduces a member variable `activated` that represents if the MemberhsipManager is trying to connect or trying to disconnect independent on the current state. * simplify catch finally blocks
1 parent 6cdc68d commit 8395919

File tree

2 files changed

+25
-11
lines changed

2 files changed

+25
-11
lines changed

src/matrixrtc/NewMembershipManager.ts

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,9 @@ export interface IMembershipManager {
4141
/**
4242
* If we are trying to join, or have successfully joined the session.
4343
* It does not reflect if the room state is already configured to represent us being joined.
44-
* It only means that the Manager is running.
44+
* It only means that the Manager should be trying to connect or to disconnect running.
45+
* The Manager is still running right after isJoined becomes false to send the disconnect events.
46+
* (A more accurate name would be `isActivated`)
4547
* @returns true if we intend to be participating in the MatrixRTC session
4648
*/
4749
isJoined(): boolean;
@@ -181,8 +183,9 @@ enum Status {
181183
* - Stop the timer for updating the state event
182184
*/
183185
export class MembershipManager implements IMembershipManager {
186+
private activated = false;
184187
public isJoined(): boolean {
185-
return this.scheduler.running;
188+
return this.activated;
186189
}
187190

188191
/**
@@ -194,26 +197,31 @@ export class MembershipManager implements IMembershipManager {
194197
* This should bubble up the the frontend to communicate that the call does not work in the current environment.
195198
*/
196199
public join(fociPreferred: Focus[], focusActive?: Focus, onError?: (error: unknown) => void): void {
197-
if (this.isJoined()) {
200+
if (this.scheduler.running) {
198201
logger.error("MembershipManager is already running. Ignoring join request.");
199202
return;
200203
}
201204
this.fociPreferred = fociPreferred;
202205
this.focusActive = focusActive;
203206
this.leavePromiseDefer = undefined;
207+
this.activated = true;
204208

205209
this.state = MembershipManager.defaultState;
206210

207211
this.scheduler
208212
.startWithJoin()
209213
.then(() => {
210-
this.leavePromiseDefer?.resolve(true);
211-
this.leavePromiseDefer = undefined;
214+
if (!this.scheduler.running) {
215+
this.leavePromiseDefer?.resolve(true);
216+
this.leavePromiseDefer = undefined;
217+
}
212218
})
213219
.catch((e) => {
214220
logger.error("MembershipManager stopped because: ", e);
215221
onError?.(e);
216-
});
222+
})
223+
// Should already be set to false when calling `leave` in non error cases.
224+
.finally(() => (this.activated = false));
217225
}
218226

219227
/**
@@ -222,13 +230,17 @@ export class MembershipManager implements IMembershipManager {
222230
* @returns true if it managed to leave and false if the timeout condition happened.
223231
*/
224232
public leave(timeout?: number): Promise<boolean> {
225-
if (!this.scheduler.running) return Promise.resolve(true);
233+
if (!this.scheduler.running) {
234+
logger.warn("Called MembershipManager.leave() even though the MembershipManager is not running");
235+
return Promise.resolve(true);
236+
}
226237

227238
// We use the promise to track if we already scheduled a leave event
228239
// So we do not check scheduler.actions/scheduler.insertions
229240
if (!this.leavePromiseDefer) {
230241
// reset scheduled actions so we will not do any new actions.
231242
this.leavePromiseDefer = defer<boolean>();
243+
this.activated = false;
232244
this.scheduler.initiateLeave();
233245
if (timeout) setTimeout(() => this.leavePromiseDefer?.resolve(false), timeout);
234246
}

src/matrixrtc/NewMembershipManagerActionScheduler.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ export type ActionUpdate =
4040
* @internal
4141
*/
4242
export class ActionScheduler {
43+
/**
44+
* This is tracking the state of the scheduler loop.
45+
* Only used to prevent starting the loop twice.
46+
*/
4347
public running = false;
4448

4549
public constructor(
@@ -111,13 +115,11 @@ export class ActionScheduler {
111115
this._actions.push(...actionUpdate.insert);
112116
}
113117
}
114-
} catch (e) {
115-
// Set the rtc session "not running" state since we cannot recover from here and the consumer user of the
118+
} finally {
119+
// Set the rtc session running state since we cannot recover from here and the consumer user of the
116120
// MatrixRTCSession class needs to manually rejoin.
117121
this.running = false;
118-
throw e;
119122
}
120-
this.running = false;
121123

122124
logger.debug("Leave MembershipManager ActionScheduler loop (no more actions)");
123125
}

0 commit comments

Comments
 (0)