@@ -34,6 +34,7 @@ import {
34
34
type IMembershipManager ,
35
35
type MembershipManagerEventHandlerMap ,
36
36
} from "./IMembershipManager.ts" ;
37
+ import { type EmptyObject } from "src/matrix.ts" ;
37
38
38
39
/* MembershipActionTypes:
39
40
@@ -77,6 +78,8 @@ On Leave: ───────── STOP ALL ABOVE
77
78
(s) Successful restart/resend
78
79
*/
79
80
81
+ const STICK_DURATION_MS = 60 * 60 * 1000 ; // 60 minutes
82
+
80
83
/**
81
84
* The different types of actions the MembershipManager can take.
82
85
* @internal
@@ -295,9 +298,9 @@ export class MembershipManager
295
298
MatrixClient ,
296
299
| "getUserId"
297
300
| "getDeviceId"
298
- | "sendStateEvent"
299
- | "_unstable_sendDelayedStateEvent"
300
301
| "_unstable_updateDelayedEvent"
302
+ | "_unstable_sendStickyEvent"
303
+ | "_unstable_sendStickyDelayedEvent"
301
304
> ,
302
305
private getOldestMembership : ( ) => CallMembership | undefined ,
303
306
public readonly sessionDescription : SessionDescription ,
@@ -371,7 +374,11 @@ export class MembershipManager
371
374
return this . joinConfig ?. membershipEventExpiryHeadroomMs ?? 5_000 ;
372
375
}
373
376
private computeNextExpiryActionTs ( iteration : number ) : number {
374
- return this . state . startTime + this . membershipEventExpiryMs * iteration - this . membershipEventExpiryHeadroomMs ;
377
+ return (
378
+ this . state . startTime +
379
+ Math . min ( this . membershipEventExpiryMs , STICK_DURATION_MS ) * iteration -
380
+ this . membershipEventExpiryHeadroomMs
381
+ ) ;
375
382
}
376
383
private get delayedLeaveEventDelayMs ( ) : number {
377
384
return this . delayedLeaveEventDelayMsOverride ?? this . joinConfig ?. delayedLeaveEventDelayMs ?? 8_000 ;
@@ -450,14 +457,15 @@ export class MembershipManager
450
457
// (Another client could have canceled it, the homeserver might have removed/lost it due to a restart, ...)
451
458
// In the `then` and `catch` block we treat both cases differently. "if (this.state.hasMemberStateEvent) {} else {}"
452
459
return await this . client
453
- . _unstable_sendDelayedStateEvent (
460
+ . _unstable_sendStickyDelayedEvent (
454
461
this . room . roomId ,
462
+ STICK_DURATION_MS ,
455
463
{
456
464
delay : this . delayedLeaveEventDelayMs ,
457
465
} ,
466
+ null ,
458
467
EventType . GroupCallMemberPrefix ,
459
- { } , // leave event
460
- this . stateKey ,
468
+ { sticky_key : this . stateKey } as EmptyObject & { sticky_key : string } , // leave event
461
469
)
462
470
. then ( ( response ) => {
463
471
this . state . expectedServerDelayLeaveTs = Date . now ( ) + this . delayedLeaveEventDelayMs ;
@@ -482,7 +490,7 @@ export class MembershipManager
482
490
if ( this . manageMaxDelayExceededSituation ( e ) ) {
483
491
return createInsertActionUpdate ( repeatActionType ) ;
484
492
}
485
- const update = this . actionUpdateFromErrors ( e , repeatActionType , "sendDelayedStateEvent " ) ;
493
+ const update = this . actionUpdateFromErrors ( e , repeatActionType , "_unstable_sendStickyDelayedEvent " ) ;
486
494
if ( update ) return update ;
487
495
488
496
if ( this . state . hasMemberStateEvent ) {
@@ -640,12 +648,10 @@ export class MembershipManager
640
648
641
649
private async sendJoinEvent ( ) : Promise < ActionUpdate > {
642
650
return await this . client
643
- . sendStateEvent (
644
- this . room . roomId ,
645
- EventType . GroupCallMemberPrefix ,
646
- this . makeMyMembership ( this . membershipEventExpiryMs ) ,
647
- this . stateKey ,
648
- )
651
+ . _unstable_sendStickyEvent ( this . room . roomId , STICK_DURATION_MS , null , EventType . GroupCallMemberPrefix , {
652
+ ...this . makeMyMembership ( this . membershipEventExpiryMs ) ,
653
+ sticky_key : this . stateKey ,
654
+ } )
649
655
. then ( ( ) => {
650
656
this . setAndEmitProbablyLeft ( false ) ;
651
657
this . state . startTime = Date . now ( ) ;
@@ -677,7 +683,11 @@ export class MembershipManager
677
683
} ;
678
684
} )
679
685
. catch ( ( e ) => {
680
- const update = this . actionUpdateFromErrors ( e , MembershipActionType . SendJoinEvent , "sendStateEvent" ) ;
686
+ const update = this . actionUpdateFromErrors (
687
+ e ,
688
+ MembershipActionType . SendJoinEvent ,
689
+ "_unstable_sendStickyEvent" ,
690
+ ) ;
681
691
if ( update ) return update ;
682
692
throw e ;
683
693
} ) ;
@@ -686,12 +696,10 @@ export class MembershipManager
686
696
private async updateExpiryOnJoinedEvent ( ) : Promise < ActionUpdate > {
687
697
const nextExpireUpdateIteration = this . state . expireUpdateIterations + 1 ;
688
698
return await this . client
689
- . sendStateEvent (
690
- this . room . roomId ,
691
- EventType . GroupCallMemberPrefix ,
692
- this . makeMyMembership ( this . membershipEventExpiryMs * nextExpireUpdateIteration ) ,
693
- this . stateKey ,
694
- )
699
+ . _unstable_sendStickyEvent ( this . room . roomId , STICK_DURATION_MS , null , EventType . GroupCallMemberPrefix , {
700
+ ...this . makeMyMembership ( this . membershipEventExpiryMs ) ,
701
+ sticky_key : this . stateKey ,
702
+ } )
695
703
. then ( ( ) => {
696
704
// Success, we reset retries and schedule update.
697
705
this . resetRateLimitCounter ( MembershipActionType . UpdateExpiry ) ;
@@ -706,22 +714,36 @@ export class MembershipManager
706
714
} ;
707
715
} )
708
716
. catch ( ( e ) => {
709
- const update = this . actionUpdateFromErrors ( e , MembershipActionType . UpdateExpiry , "sendStateEvent" ) ;
717
+ const update = this . actionUpdateFromErrors (
718
+ e ,
719
+ MembershipActionType . UpdateExpiry ,
720
+ "_unstable_sendStickyEvent" ,
721
+ ) ;
710
722
if ( update ) return update ;
711
723
712
724
throw e ;
713
725
} ) ;
714
726
}
715
727
private async sendFallbackLeaveEvent ( ) : Promise < ActionUpdate > {
716
728
return await this . client
717
- . sendStateEvent ( this . room . roomId , EventType . GroupCallMemberPrefix , { } , this . stateKey )
729
+ . _unstable_sendStickyEvent (
730
+ this . room . roomId ,
731
+ STICK_DURATION_MS ,
732
+ null ,
733
+ EventType . GroupCallMemberPrefix ,
734
+ { sticky_key : this . stateKey } as EmptyObject & { sticky_key : string } , // leave event
735
+ )
718
736
. then ( ( ) => {
719
737
this . resetRateLimitCounter ( MembershipActionType . SendLeaveEvent ) ;
720
738
this . state . hasMemberStateEvent = false ;
721
739
return { replace : [ ] } ;
722
740
} )
723
741
. catch ( ( e ) => {
724
- const update = this . actionUpdateFromErrors ( e , MembershipActionType . SendLeaveEvent , "sendStateEvent" ) ;
742
+ const update = this . actionUpdateFromErrors (
743
+ e ,
744
+ MembershipActionType . SendLeaveEvent ,
745
+ "_unstable_sendStickyEvent" ,
746
+ ) ;
725
747
if ( update ) return update ;
726
748
throw e ;
727
749
} ) ;
0 commit comments