@@ -44,6 +44,11 @@ def __init__(self, database: DatabasePool, db_conn: Connection, hs: "HomeServer"
4444 self ._remove_deactivated_pushers ,
4545 )
4646
47+ self .db_pool .updates .register_background_update_handler (
48+ "remove_stale_pushers" ,
49+ self ._remove_stale_pushers ,
50+ )
51+
4752 def _decode_pushers_rows (self , rows : Iterable [dict ]) -> Iterator [PusherConfig ]:
4853 """JSON-decode the data in the rows returned from the `pushers` table
4954
@@ -337,6 +342,53 @@ def _delete_pushers(txn) -> int:
337342
338343 return number_deleted
339344
345+ async def _remove_stale_pushers (self , progress : dict , batch_size : int ) -> int :
346+ """A background update that deletes all pushers for logged out devices.
347+
348+ Note that we don't proacively tell the pusherpool that we've deleted
349+ these (just because its a bit off a faff to do from here), but they will
350+ get cleaned up at the next restart
351+ """
352+
353+ last_pusher = progress .get ("last_pusher" , 0 )
354+
355+ def _delete_pushers (txn ) -> int :
356+
357+ sql = """
358+ SELECT p.id, access_token FROM pushers AS p
359+ LEFT JOIN access_tokens AS a ON (p.access_token = a.id)
360+ WHERE p.id > ?
361+ ORDER BY p.id ASC
362+ LIMIT ?
363+ """
364+
365+ txn .execute (sql , (last_pusher , batch_size ))
366+ pushers = [(row [0 ], row [1 ]) for row in txn ]
367+
368+ self .db_pool .simple_delete_many_txn (
369+ txn ,
370+ table = "pushers" ,
371+ column = "id" ,
372+ iterable = (pusher_id for pusher_id , token in pushers if token is None ),
373+ keyvalues = {},
374+ )
375+
376+ if pushers :
377+ self .db_pool .updates ._background_update_progress_txn (
378+ txn , "remove_stale_pushers" , {"last_pusher" : pushers [- 1 ][0 ]}
379+ )
380+
381+ return len (pushers )
382+
383+ number_deleted = await self .db_pool .runInteraction (
384+ "_remove_stale_pushers" , _delete_pushers
385+ )
386+
387+ if number_deleted < batch_size :
388+ await self .db_pool .updates ._end_background_update ("remove_stale_pushers" )
389+
390+ return number_deleted
391+
340392
341393class PusherStore (PusherWorkerStore ):
342394 def get_pushers_stream_token (self ) -> int :
0 commit comments