Skip to content

Commit 98d119d

Browse files
authored
Add client.waitUntilRoomReadyForGroupCalls() (#2641)
See comment, although this still feels like a poor solution to the problem. Might be better if the js-sdk processed everything internally before emitting the 'Room' event (or indeed before joinRoom resolved) so the app knows everything is ready when it gets that event.
1 parent aca51fd commit 98d119d

File tree

2 files changed

+49
-4
lines changed

2 files changed

+49
-4
lines changed

src/client.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -869,7 +869,6 @@ type EmittedEvents = ClientEvent
869869
| GroupCallEventHandlerEvent.Incoming
870870
| GroupCallEventHandlerEvent.Ended
871871
| GroupCallEventHandlerEvent.Participants
872-
| GroupCallEventHandlerEvent.Room
873872
| HttpApiEvent.SessionLoggedOut
874873
| HttpApiEvent.NoConsent
875874
| BeaconEvent;
@@ -1594,6 +1593,21 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
15941593
).create();
15951594
}
15961595

1596+
/**
1597+
* Wait until an initial state for the given room has been processed by the
1598+
* client and the client is aware of any ongoing group calls. Awaiting on
1599+
* the promise returned by this method before calling getGroupCallForRoom()
1600+
* avoids races where getGroupCallForRoom is called before the state for that
1601+
* room has been processed. It does not, however, fix other races, eg. two
1602+
* clients both creating a group call at the same time.
1603+
* @param roomId The room ID to wait for
1604+
* @returns A promise that resolves once existing group calls in the room
1605+
* have been processed.
1606+
*/
1607+
public waitUntilRoomReadyForGroupCalls(roomId: string): Promise<void> {
1608+
return this.groupCallEventHandler.waitUntilRoomReadyForGroupCalls(roomId);
1609+
}
1610+
15971611
/**
15981612
* Get an existing group call for the provided room.
15991613
* @param roomId

src/webrtc/groupCallEventHandler.ts

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,28 @@ export enum GroupCallEventHandlerEvent {
3434
Incoming = "GroupCall.incoming",
3535
Ended = "GroupCall.ended",
3636
Participants = "GroupCall.participants",
37-
Room = "GroupCall.Room",
3837
}
3938

4039
export type GroupCallEventHandlerEventHandlerMap = {
4140
[GroupCallEventHandlerEvent.Incoming]: (call: GroupCall) => void;
4241
[GroupCallEventHandlerEvent.Ended]: (call: GroupCall) => void;
4342
[GroupCallEventHandlerEvent.Participants]: (participants: RoomMember[], call: GroupCall) => void;
44-
[GroupCallEventHandlerEvent.Room]: (room: Room) => void;
4543
};
4644

45+
interface RoomDeferred {
46+
prom: Promise<void>;
47+
resolve?: () => void;
48+
}
49+
4750
export class GroupCallEventHandler {
4851
public groupCalls = new Map<string, GroupCall>(); // roomId -> GroupCall
4952

53+
// All rooms we know about and whether we've seen a 'Room' event
54+
// for them. The promise will be fulfilled once we've processed that
55+
// event which means we're "up to date" on what calls are in a room
56+
// and get
57+
private roomDeferreds = new Map<string, RoomDeferred>();
58+
5059
constructor(private client: MatrixClient) { }
5160

5261
public async start(): Promise<void> {
@@ -82,6 +91,26 @@ export class GroupCallEventHandler {
8291
this.client.removeListener(RoomStateEvent.Events, this.onRoomStateChanged);
8392
}
8493

94+
private getRoomDeferred(roomId: string): RoomDeferred {
95+
let deferred: RoomDeferred = this.roomDeferreds.get(roomId);
96+
if (deferred === undefined) {
97+
let resolveFunc: () => void;
98+
deferred = {
99+
prom: new Promise<void>(resolve => {
100+
resolveFunc = resolve;
101+
}),
102+
};
103+
deferred.resolve = resolveFunc;
104+
this.roomDeferreds.set(roomId, deferred);
105+
}
106+
107+
return deferred;
108+
}
109+
110+
public waitUntilRoomReadyForGroupCalls(roomId: string): Promise<void> {
111+
return this.getRoomDeferred(roomId).prom;
112+
}
113+
85114
public getGroupCallById(groupCallId: string): GroupCall {
86115
return [...this.groupCalls.values()].find((groupCall) => groupCall.groupCallId === groupCallId);
87116
}
@@ -98,9 +127,11 @@ export class GroupCallEventHandler {
98127
}
99128

100129
this.createGroupCallFromRoomStateEvent(callEvent);
101-
this.client.emit(GroupCallEventHandlerEvent.Room, room);
102130
break;
103131
}
132+
133+
logger.info("Group call event handler processed room", room);
134+
this.getRoomDeferred(room.roomId).resolve();
104135
}
105136

106137
private createGroupCallFromRoomStateEvent(event: MatrixEvent): GroupCall | undefined {

0 commit comments

Comments
 (0)