@@ -185,6 +185,9 @@ export class GroupCall extends TypedEventEmitter<
185185 private resendMemberStateTimer : ReturnType < typeof setInterval > | null = null ;
186186 private initWithAudioMuted = false ;
187187 private initWithVideoMuted = false ;
188+ // We use this as a set of mutexes, effectively, to make sure we only enter the function
189+ // to process a member state event once at any one time for each member
190+ private processingMemberStateEvent = new Map < string , boolean > ( ) ;
188191
189192 constructor (
190193 private client : MatrixClient ,
@@ -201,7 +204,8 @@ export class GroupCall extends TypedEventEmitter<
201204 this . groupCallId = groupCallId || genCallID ( ) ;
202205
203206 for ( const stateEvent of this . getMemberStateEvents ( ) ) {
204- this . onMemberStateChanged ( stateEvent ) ;
207+ logger . debug ( "Processing member states on group call initialisation" ) ;
208+ this . processMemberStateEvent ( stateEvent ) ;
205209 }
206210 }
207211
@@ -332,7 +336,8 @@ export class GroupCall extends TypedEventEmitter<
332336 // Set up participants for the members currently in the room.
333337 // Other members will be picked up by the RoomState.members event.
334338 for ( const stateEvent of this . getMemberStateEvents ( ) ) {
335- this . onMemberStateChanged ( stateEvent ) ;
339+ logger . debug ( "Processing member states on call enter" ) ;
340+ this . processMemberStateEvent ( stateEvent ) ;
336341 }
337342
338343 this . retryCallLoopTimeout = setTimeout ( this . onRetryCallLoop , this . retryCallInterval ) ;
@@ -754,6 +759,25 @@ export class GroupCall extends TypedEventEmitter<
754759 }
755760
756761 public onMemberStateChanged = async ( event : MatrixEvent ) => {
762+ logger . debug ( "Processing member states on member state change" ) ;
763+ return this . processMemberStateEvent ( event ) ;
764+ } ;
765+
766+ private processMemberStateEvent = async ( event : MatrixEvent ) => {
767+ if ( this . processingMemberStateEvent . has ( event . getStateKey ( ) ) ) {
768+ logger . debug ( `Already processing meber state event for ${ event . getStateKey ( ) } ` ) ;
769+ return ;
770+ }
771+
772+ this . processingMemberStateEvent . set ( event . getStateKey ( ) , true ) ;
773+ try {
774+ return this . processMemberStateEventInternal ( event ) ;
775+ } finally {
776+ this . processingMemberStateEvent . delete ( event . getStateKey ( ) ) ;
777+ }
778+ } ;
779+
780+ private processMemberStateEventInternal = async ( event : MatrixEvent ) => {
757781 // If we haven't entered the call yet, we don't care
758782 if ( this . state !== GroupCallState . Entered ) {
759783 return ;
@@ -861,7 +885,9 @@ export class GroupCall extends TypedEventEmitter<
861885 const requestScreenshareFeed = opponentDevice . feeds . some (
862886 ( feed ) => feed . purpose === SDPStreamMetadataPurpose . Screenshare ) ;
863887
864- logger . log ( `Placing call to ${ member . userId } .` ) ;
888+ logger . debug (
889+ `Placing call to ${ member . userId } /${ opponentDevice . device_id } session ID ${ opponentDevice . session_id } .` ,
890+ ) ;
865891
866892 try {
867893 await newCall . placeCallWithCallFeeds (
@@ -889,8 +915,10 @@ export class GroupCall extends TypedEventEmitter<
889915 }
890916
891917 if ( existingCall ) {
918+ logger . debug ( `Replacing call ${ existingCall . callId } to ${ member . userId } with ${ newCall . callId } ` ) ;
892919 this . replaceCall ( existingCall , newCall , CallErrorCode . NewSession ) ;
893920 } else {
921+ logger . debug ( `Adding call ${ newCall . callId } to ${ member . userId } ` ) ;
894922 this . addCall ( newCall ) ;
895923 }
896924 } ;
@@ -928,7 +956,8 @@ export class GroupCall extends TypedEventEmitter<
928956
929957 if ( ! existingCall && retryCallCount < 3 ) {
930958 this . retryCallCounts . set ( memberId , retryCallCount + 1 ) ;
931- this . onMemberStateChanged ( event ) ;
959+ logger . debug ( "Processing member states on call retry" ) ;
960+ this . processMemberStateEvent ( event ) ;
932961 }
933962 }
934963
0 commit comments