@@ -106,6 +106,11 @@ def __init__(
106106            "AccountDataAndTagsChangeCache" , account_max 
107107        )
108108
109+         self .db_pool .updates .register_background_update_handler (
110+             "delete_account_data_for_deactivated_users" ,
111+             self ._delete_account_data_for_deactivated_users ,
112+         )
113+ 
109114    def  get_max_account_data_stream_id (self ) ->  int :
110115        """Get the current max stream ID for account data stream 
111116
@@ -549,72 +554,121 @@ def _add_account_data_for_user(
549554
550555    async  def  purge_account_data_for_user (self , user_id : str ) ->  None :
551556        """ 
552-         Removes the account data for a user. 
557+         Removes ALL the account data for a user. 
558+         Intended to be used upon user deactivation. 
553559
554-         This is intended to be used upon user deactivation and also removes any 
555-         derived information from account data (e.g. push rules and ignored users). 
560+         Also purges the user from the ignored_users cache table 
561+         and the push_rules cache tables. 
562+         """ 
556563
557-         Args: 
558-             user_id: The user ID to remove data for. 
564+         await  self .db_pool .runInteraction (
565+             "purge_account_data_for_user_txn" ,
566+             self ._purge_account_data_for_user_txn ,
567+             user_id ,
568+         )
569+ 
570+     def  _purge_account_data_for_user_txn (
571+         self , txn : LoggingTransaction , user_id : str 
572+     ) ->  None :
559573        """ 
574+         See `purge_account_data_for_user`. 
575+         """ 
576+         # Purge from the primary account_data tables. 
577+         self .db_pool .simple_delete_txn (
578+             txn , table = "account_data" , keyvalues = {"user_id" : user_id }
579+         )
560580
561-         def  purge_account_data_for_user_txn (txn : LoggingTransaction ) ->  None :
562-             # Purge from the primary account_data tables. 
563-             self .db_pool .simple_delete_txn (
564-                 txn , table = "account_data" , keyvalues = {"user_id" : user_id }
565-             )
581+         self .db_pool .simple_delete_txn (
582+             txn , table = "room_account_data" , keyvalues = {"user_id" : user_id }
583+         )
566584
567-             self .db_pool .simple_delete_txn (
568-                 txn , table = "room_account_data" , keyvalues = {"user_id" : user_id }
569-             )
585+         # Purge from ignored_users where this user is the ignorer. 
586+         # N.B. We don't purge where this user is the ignoree, because that 
587+         #      interferes with other users' account data. 
588+         #      It's also not this user's data to delete! 
589+         self .db_pool .simple_delete_txn (
590+             txn , table = "ignored_users" , keyvalues = {"ignorer_user_id" : user_id }
591+         )
570592
571-             # Purge from ignored_users where this user is the ignorer. 
572-             # N.B. We don't purge where this user is the ignoree, because that 
573-             #      interferes with other users' account data. 
574-             #      It's also not this user's data to delete! 
575-             self .db_pool .simple_delete_txn (
576-                 txn , table = "ignored_users" , keyvalues = {"ignorer_user_id" : user_id }
577-             )
593+         # Remove the push rules 
594+         self .db_pool .simple_delete_txn (
595+             txn , table = "push_rules" , keyvalues = {"user_name" : user_id }
596+         )
597+         self .db_pool .simple_delete_txn (
598+             txn , table = "push_rules_enable" , keyvalues = {"user_name" : user_id }
599+         )
600+         self .db_pool .simple_delete_txn (
601+             txn , table = "push_rules_stream" , keyvalues = {"user_id" : user_id }
602+         )
578603
579-             # Remove the push rules 
580-             self .db_pool .simple_delete_txn (
581-                 txn , table = "push_rules" , keyvalues = {"user_name" : user_id }
582-             )
583-             self .db_pool .simple_delete_txn (
584-                 txn , table = "push_rules_enable" , keyvalues = {"user_name" : user_id }
585-             )
586-             self .db_pool .simple_delete_txn (
587-                 txn , table = "push_rules_stream" , keyvalues = {"user_id" : user_id }
588-             )
604+         # Invalidate caches as appropriate 
605+         self ._invalidate_cache_and_stream (
606+             txn , self .get_account_data_for_room_and_type , (user_id ,)
607+         )
608+         self ._invalidate_cache_and_stream (
609+             txn , self .get_account_data_for_user , (user_id ,)
610+         )
611+         self ._invalidate_cache_and_stream (
612+             txn , self .get_global_account_data_by_type_for_user , (user_id ,)
613+         )
614+         self ._invalidate_cache_and_stream (
615+             txn , self .get_account_data_for_room , (user_id ,)
616+         )
617+         self ._invalidate_cache_and_stream (txn , self .get_push_rules_for_user , (user_id ,))
618+         self ._invalidate_cache_and_stream (
619+             txn , self .get_push_rules_enabled_for_user , (user_id ,)
620+         )
621+         # This user might be contained in the ignored_by cache for other users, 
622+         # so we have to invalidate it all. 
623+         self ._invalidate_all_cache_and_stream (txn , self .ignored_by )
589624
590-             # Invalidate caches as appropriate 
591-             self ._invalidate_cache_and_stream (
592-                 txn , self .get_account_data_for_room_and_type , (user_id ,)
593-             )
594-             self ._invalidate_cache_and_stream (
595-                 txn , self .get_account_data_for_user , (user_id ,)
596-             )
597-             self ._invalidate_cache_and_stream (
598-                 txn , self .get_global_account_data_by_type_for_user , (user_id ,)
599-             )
600-             self ._invalidate_cache_and_stream (
601-                 txn , self .get_account_data_for_room , (user_id ,)
602-             )
603-             self ._invalidate_cache_and_stream (
604-                 txn , self .get_push_rules_for_user , (user_id ,)
605-             )
606-             self ._invalidate_cache_and_stream (
607-                 txn , self .get_push_rules_enabled_for_user , (user_id ,)
608-             )
609-             # This user might be contained in the ignored_by cache for other users, 
610-             # so we have to invalidate it all. 
611-             self ._invalidate_all_cache_and_stream (txn , self .ignored_by )
625+     async  def  _delete_account_data_for_deactivated_users (
626+         self , progress : dict , batch_size : int 
627+     ) ->  int :
628+         """ 
629+         Retroactively purges account data for users that have already been deactivated. 
630+         Gets run as a background update caused by a schema delta. 
631+         """ 
612632
613-         await  self .db_pool .runInteraction (
614-             "purge_account_data_for_user_txn" ,
615-             purge_account_data_for_user_txn ,
633+         last_user : str  =  progress .get ("last_user" , "" )
634+ 
635+         def  _delete_account_data_for_deactivated_users_txn (
636+             txn : LoggingTransaction ,
637+         ) ->  int :
638+             sql  =  """ 
639+                 SELECT name FROM users 
640+                 WHERE deactivated = ? and name > ? 
641+                 ORDER BY name ASC 
642+                 LIMIT ? 
643+             """ 
644+ 
645+             txn .execute (sql , (1 , last_user , batch_size ))
646+             users  =  [row [0 ] for  row  in  txn ]
647+ 
648+             for  user  in  users :
649+                 self ._purge_account_data_for_user_txn (txn , user_id = user )
650+ 
651+             if  users :
652+                 self .db_pool .updates ._background_update_progress_txn (
653+                     txn ,
654+                     "delete_account_data_for_deactivated_users" ,
655+                     {"last_user" : users [- 1 ]},
656+                 )
657+ 
658+             return  len (users )
659+ 
660+         number_deleted  =  await  self .db_pool .runInteraction (
661+             "_delete_account_data_for_deactivated_users" ,
662+             _delete_account_data_for_deactivated_users_txn ,
616663        )
617664
665+         if  number_deleted  <  batch_size :
666+             await  self .db_pool .updates ._end_background_update (
667+                 "delete_account_data_for_deactivated_users" 
668+             )
669+ 
670+         return  number_deleted 
671+ 
618672
619673class  AccountDataStore (AccountDataWorkerStore ):
620674    pass 
0 commit comments