@@ -82,6 +82,7 @@ def __init__(self, hs: "HomeServer"):
8282 self .event_auth_handler = hs .get_event_auth_handler ()
8383
8484 self .member_linearizer : Linearizer = Linearizer (name = "member" )
85+ self .member_as_limiter = Linearizer (max_count = 10 , name = "member_as_limiter" )
8586
8687 self .clock = hs .get_clock ()
8788 self .spam_checker = hs .get_spam_checker ()
@@ -500,25 +501,32 @@ async def update_membership(
500501
501502 key = (room_id ,)
502503
503- with (await self .member_linearizer .queue (key )):
504- result = await self .update_membership_locked (
505- requester ,
506- target ,
507- room_id ,
508- action ,
509- txn_id = txn_id ,
510- remote_room_hosts = remote_room_hosts ,
511- third_party_signed = third_party_signed ,
512- ratelimit = ratelimit ,
513- content = content ,
514- new_room = new_room ,
515- require_consent = require_consent ,
516- outlier = outlier ,
517- historical = historical ,
518- allow_no_prev_events = allow_no_prev_events ,
519- prev_event_ids = prev_event_ids ,
520- auth_event_ids = auth_event_ids ,
521- )
504+ as_id = object ()
505+ if requester .app_service :
506+ as_id = requester .app_service .id
507+
508+ # We first linearise by the application service (to try to limit concurrent joins
509+ # by application services), and then by room ID.
510+ with (await self .member_as_limiter .queue (as_id )):
511+ with (await self .member_linearizer .queue (key )):
512+ result = await self .update_membership_locked (
513+ requester ,
514+ target ,
515+ room_id ,
516+ action ,
517+ txn_id = txn_id ,
518+ remote_room_hosts = remote_room_hosts ,
519+ third_party_signed = third_party_signed ,
520+ ratelimit = ratelimit ,
521+ content = content ,
522+ new_room = new_room ,
523+ require_consent = require_consent ,
524+ outlier = outlier ,
525+ historical = historical ,
526+ allow_no_prev_events = allow_no_prev_events ,
527+ prev_event_ids = prev_event_ids ,
528+ auth_event_ids = auth_event_ids ,
529+ )
522530
523531 return result
524532
0 commit comments