mirror of
https://git.anonymousland.org/anonymousland/synapse.git
synced 2025-05-03 00:14:54 -04:00
Convert internal pusher dicts to attrs classes. (#8940)
This improves type hinting and should use less memory.
This commit is contained in:
parent
7a332850e6
commit
bd30cfe86a
17 changed files with 266 additions and 204 deletions
|
@ -15,7 +15,7 @@
|
|||
# limitations under the License.
|
||||
|
||||
import logging
|
||||
from typing import TYPE_CHECKING, Any, Dict, Optional
|
||||
from typing import TYPE_CHECKING, Dict, Iterable, Optional
|
||||
|
||||
from prometheus_client import Gauge
|
||||
|
||||
|
@ -23,9 +23,9 @@ from synapse.metrics.background_process_metrics import (
|
|||
run_as_background_process,
|
||||
wrap_as_background_process,
|
||||
)
|
||||
from synapse.push import Pusher, PusherConfigException
|
||||
from synapse.push import Pusher, PusherConfig, PusherConfigException
|
||||
from synapse.push.pusher import PusherFactory
|
||||
from synapse.types import RoomStreamToken
|
||||
from synapse.types import JsonDict, RoomStreamToken
|
||||
from synapse.util.async_helpers import concurrently_execute
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
@ -77,7 +77,7 @@ class PusherPool:
|
|||
# map from user id to app_id:pushkey to pusher
|
||||
self.pushers = {} # type: Dict[str, Dict[str, Pusher]]
|
||||
|
||||
def start(self):
|
||||
def start(self) -> None:
|
||||
"""Starts the pushers off in a background process.
|
||||
"""
|
||||
if not self._should_start_pushers:
|
||||
|
@ -87,16 +87,16 @@ class PusherPool:
|
|||
|
||||
async def add_pusher(
|
||||
self,
|
||||
user_id,
|
||||
access_token,
|
||||
kind,
|
||||
app_id,
|
||||
app_display_name,
|
||||
device_display_name,
|
||||
pushkey,
|
||||
lang,
|
||||
data,
|
||||
profile_tag="",
|
||||
user_id: str,
|
||||
access_token: Optional[int],
|
||||
kind: str,
|
||||
app_id: str,
|
||||
app_display_name: str,
|
||||
device_display_name: str,
|
||||
pushkey: str,
|
||||
lang: Optional[str],
|
||||
data: JsonDict,
|
||||
profile_tag: str = "",
|
||||
) -> Optional[Pusher]:
|
||||
"""Creates a new pusher and adds it to the pool
|
||||
|
||||
|
@ -111,21 +111,23 @@ class PusherPool:
|
|||
# recreated, added and started: this means we have only one
|
||||
# code path adding pushers.
|
||||
self.pusher_factory.create_pusher(
|
||||
{
|
||||
"id": None,
|
||||
"user_name": user_id,
|
||||
"kind": kind,
|
||||
"app_id": app_id,
|
||||
"app_display_name": app_display_name,
|
||||
"device_display_name": device_display_name,
|
||||
"pushkey": pushkey,
|
||||
"ts": time_now_msec,
|
||||
"lang": lang,
|
||||
"data": data,
|
||||
"last_stream_ordering": None,
|
||||
"last_success": None,
|
||||
"failing_since": None,
|
||||
}
|
||||
PusherConfig(
|
||||
id=None,
|
||||
user_name=user_id,
|
||||
access_token=access_token,
|
||||
profile_tag=profile_tag,
|
||||
kind=kind,
|
||||
app_id=app_id,
|
||||
app_display_name=app_display_name,
|
||||
device_display_name=device_display_name,
|
||||
pushkey=pushkey,
|
||||
ts=time_now_msec,
|
||||
lang=lang,
|
||||
data=data,
|
||||
last_stream_ordering=None,
|
||||
last_success=None,
|
||||
failing_since=None,
|
||||
)
|
||||
)
|
||||
|
||||
# create the pusher setting last_stream_ordering to the current maximum
|
||||
|
@ -151,43 +153,44 @@ class PusherPool:
|
|||
return pusher
|
||||
|
||||
async def remove_pushers_by_app_id_and_pushkey_not_user(
|
||||
self, app_id, pushkey, not_user_id
|
||||
):
|
||||
self, app_id: str, pushkey: str, not_user_id: str
|
||||
) -> None:
|
||||
to_remove = await self.store.get_pushers_by_app_id_and_pushkey(app_id, pushkey)
|
||||
for p in to_remove:
|
||||
if p["user_name"] != not_user_id:
|
||||
if p.user_name != not_user_id:
|
||||
logger.info(
|
||||
"Removing pusher for app id %s, pushkey %s, user %s",
|
||||
app_id,
|
||||
pushkey,
|
||||
p["user_name"],
|
||||
p.user_name,
|
||||
)
|
||||
await self.remove_pusher(p["app_id"], p["pushkey"], p["user_name"])
|
||||
await self.remove_pusher(p.app_id, p.pushkey, p.user_name)
|
||||
|
||||
async def remove_pushers_by_access_token(self, user_id, access_tokens):
|
||||
async def remove_pushers_by_access_token(
|
||||
self, user_id: str, access_tokens: Iterable[int]
|
||||
) -> None:
|
||||
"""Remove the pushers for a given user corresponding to a set of
|
||||
access_tokens.
|
||||
|
||||
Args:
|
||||
user_id (str): user to remove pushers for
|
||||
access_tokens (Iterable[int]): access token *ids* to remove pushers
|
||||
for
|
||||
user_id: user to remove pushers for
|
||||
access_tokens: access token *ids* to remove pushers for
|
||||
"""
|
||||
if not self._pusher_shard_config.should_handle(self._instance_name, user_id):
|
||||
return
|
||||
|
||||
tokens = set(access_tokens)
|
||||
for p in await self.store.get_pushers_by_user_id(user_id):
|
||||
if p["access_token"] in tokens:
|
||||
if p.access_token in tokens:
|
||||
logger.info(
|
||||
"Removing pusher for app id %s, pushkey %s, user %s",
|
||||
p["app_id"],
|
||||
p["pushkey"],
|
||||
p["user_name"],
|
||||
p.app_id,
|
||||
p.pushkey,
|
||||
p.user_name,
|
||||
)
|
||||
await self.remove_pusher(p["app_id"], p["pushkey"], p["user_name"])
|
||||
await self.remove_pusher(p.app_id, p.pushkey, p.user_name)
|
||||
|
||||
def on_new_notifications(self, max_token: RoomStreamToken):
|
||||
def on_new_notifications(self, max_token: RoomStreamToken) -> None:
|
||||
if not self.pushers:
|
||||
# nothing to do here.
|
||||
return
|
||||
|
@ -206,7 +209,7 @@ class PusherPool:
|
|||
self._on_new_notifications(max_token)
|
||||
|
||||
@wrap_as_background_process("on_new_notifications")
|
||||
async def _on_new_notifications(self, max_token: RoomStreamToken):
|
||||
async def _on_new_notifications(self, max_token: RoomStreamToken) -> None:
|
||||
# We just use the minimum stream ordering and ignore the vector clock
|
||||
# component. This is safe to do as long as we *always* ignore the vector
|
||||
# clock components.
|
||||
|
@ -236,7 +239,9 @@ class PusherPool:
|
|||
except Exception:
|
||||
logger.exception("Exception in pusher on_new_notifications")
|
||||
|
||||
async def on_new_receipts(self, min_stream_id, max_stream_id, affected_room_ids):
|
||||
async def on_new_receipts(
|
||||
self, min_stream_id: int, max_stream_id: int, affected_room_ids: Iterable[str]
|
||||
) -> None:
|
||||
if not self.pushers:
|
||||
# nothing to do here.
|
||||
return
|
||||
|
@ -280,14 +285,14 @@ class PusherPool:
|
|||
|
||||
resultlist = await self.store.get_pushers_by_app_id_and_pushkey(app_id, pushkey)
|
||||
|
||||
pusher_dict = None
|
||||
pusher_config = None
|
||||
for r in resultlist:
|
||||
if r["user_name"] == user_id:
|
||||
pusher_dict = r
|
||||
if r.user_name == user_id:
|
||||
pusher_config = r
|
||||
|
||||
pusher = None
|
||||
if pusher_dict:
|
||||
pusher = await self._start_pusher(pusher_dict)
|
||||
if pusher_config:
|
||||
pusher = await self._start_pusher(pusher_config)
|
||||
|
||||
return pusher
|
||||
|
||||
|
@ -302,44 +307,44 @@ class PusherPool:
|
|||
|
||||
logger.info("Started pushers")
|
||||
|
||||
async def _start_pusher(self, pusherdict: Dict[str, Any]) -> Optional[Pusher]:
|
||||
async def _start_pusher(self, pusher_config: PusherConfig) -> Optional[Pusher]:
|
||||
"""Start the given pusher
|
||||
|
||||
Args:
|
||||
pusherdict: dict with the values pulled from the db table
|
||||
pusher_config: The pusher configuration with the values pulled from the db table
|
||||
|
||||
Returns:
|
||||
The newly created pusher or None.
|
||||
"""
|
||||
if not self._pusher_shard_config.should_handle(
|
||||
self._instance_name, pusherdict["user_name"]
|
||||
self._instance_name, pusher_config.user_name
|
||||
):
|
||||
return None
|
||||
|
||||
try:
|
||||
p = self.pusher_factory.create_pusher(pusherdict)
|
||||
p = self.pusher_factory.create_pusher(pusher_config)
|
||||
except PusherConfigException as e:
|
||||
logger.warning(
|
||||
"Pusher incorrectly configured id=%i, user=%s, appid=%s, pushkey=%s: %s",
|
||||
pusherdict["id"],
|
||||
pusherdict.get("user_name"),
|
||||
pusherdict.get("app_id"),
|
||||
pusherdict.get("pushkey"),
|
||||
pusher_config.id,
|
||||
pusher_config.user_name,
|
||||
pusher_config.app_id,
|
||||
pusher_config.pushkey,
|
||||
e,
|
||||
)
|
||||
return None
|
||||
except Exception:
|
||||
logger.exception(
|
||||
"Couldn't start pusher id %i: caught Exception", pusherdict["id"],
|
||||
"Couldn't start pusher id %i: caught Exception", pusher_config.id,
|
||||
)
|
||||
return None
|
||||
|
||||
if not p:
|
||||
return None
|
||||
|
||||
appid_pushkey = "%s:%s" % (pusherdict["app_id"], pusherdict["pushkey"])
|
||||
appid_pushkey = "%s:%s" % (pusher_config.app_id, pusher_config.pushkey)
|
||||
|
||||
byuser = self.pushers.setdefault(pusherdict["user_name"], {})
|
||||
byuser = self.pushers.setdefault(pusher_config.user_name, {})
|
||||
if appid_pushkey in byuser:
|
||||
byuser[appid_pushkey].on_stop()
|
||||
byuser[appid_pushkey] = p
|
||||
|
@ -349,8 +354,8 @@ class PusherPool:
|
|||
# Check if there *may* be push to process. We do this as this check is a
|
||||
# lot cheaper to do than actually fetching the exact rows we need to
|
||||
# push.
|
||||
user_id = pusherdict["user_name"]
|
||||
last_stream_ordering = pusherdict["last_stream_ordering"]
|
||||
user_id = pusher_config.user_name
|
||||
last_stream_ordering = pusher_config.last_stream_ordering
|
||||
if last_stream_ordering:
|
||||
have_notifs = await self.store.get_if_maybe_push_in_range_for_user(
|
||||
user_id, last_stream_ordering
|
||||
|
@ -364,7 +369,7 @@ class PusherPool:
|
|||
|
||||
return p
|
||||
|
||||
async def remove_pusher(self, app_id, pushkey, user_id):
|
||||
async def remove_pusher(self, app_id: str, pushkey: str, user_id: str) -> None:
|
||||
appid_pushkey = "%s:%s" % (app_id, pushkey)
|
||||
|
||||
byuser = self.pushers.get(user_id, {})
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue