@@ -243,7 +243,7 @@ export class MembershipManager
243243 this . logger . warn ( "Missing own membership: force re-join" ) ;
244244 this . state . hasMemberStateEvent = false ;
245245
246- if ( this . scheduler . actions . find ( ( a ) => sendingMembershipActions . includes ( a . type as MembershipActionType ) ) ) {
246+ if ( this . scheduler . actions . some ( ( a ) => sendingMembershipActions . includes ( a . type as MembershipActionType ) ) ) {
247247 this . logger . error (
248248 "tried adding another `SendDelayedEvent` actions even though we already have one in the Queue\nActionQueueOnMemberUpdate:" ,
249249 this . scheduler . actions ,
@@ -624,8 +624,21 @@ export class MembershipManager
624624 this . state . expireUpdateIterations = 1 ;
625625 this . state . hasMemberStateEvent = true ;
626626 this . resetRateLimitCounter ( MembershipActionType . SendJoinEvent ) ;
627+ // An UpdateExpiry action might be left over from a previous join event.
628+ // We can reach sendJoinEvent when the delayed leave event gets send by the HS.
629+ // The branch where we might have a leftover UpdateExpiry action is:
630+ // RestartDelayedEvent (cannot find it, server removed it)
631+ // -> SendDelayedEvent (send new delayed event)
632+ // -> SendJoinEvent (here with a still scheduled UpdateExpiry action)
633+ const actionsWithoutUpdateExpiry = this . scheduler . actions . filter (
634+ ( a ) =>
635+ a . type !== MembershipActionType . UpdateExpiry && // A new UpdateExpiry action with an updated will be scheduled,
636+ a . type !== MembershipActionType . SendJoinEvent , // Manually remove the SendJoinEvent action,
637+ ) ;
627638 return {
628- insert : [
639+ replace : [
640+ ...actionsWithoutUpdateExpiry ,
641+ // To check if the delayed event is still there or got removed by inserting the stateEvent, we need to restart it.
629642 { ts : Date . now ( ) , type : MembershipActionType . RestartDelayedEvent } ,
630643 {
631644 ts : this . computeNextExpiryActionTs ( this . state . expireUpdateIterations ) ,
0 commit comments