mirror of
https://mau.dev/maunium/synapse.git
synced 2024-11-15 14:32:30 +01:00
Clean up startup for the pusher (#6558)
* Remove redundant python2 support code `str.decode()` doesn't exist on python3, so presumably this code was doing nothing * Filter out pushers with corrupt data When we get a row with unparsable json, drop the row, rather than returning a row with null `data`, which will then cause an explosion later on. * Improve logging when we can't start a pusher Log the ID to help us understand the problem * Make email pusher setup more robust We know we'll have a `data` member, since that comes from the database. What we *don't* know is if that is a dict, and if that has a `brand` member, and if that member is a string.
This commit is contained in:
parent
7963ca83cb
commit
d6752ce5da
7 changed files with 44 additions and 42 deletions
1
changelog.d/6558.misc
Normal file
1
changelog.d/6558.misc
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Clean up logs from the push notifier at startup.
|
|
@ -80,9 +80,11 @@ class PusherFactory(object):
|
||||||
return EmailPusher(self.hs, pusherdict, mailer)
|
return EmailPusher(self.hs, pusherdict, mailer)
|
||||||
|
|
||||||
def _app_name_from_pusherdict(self, pusherdict):
|
def _app_name_from_pusherdict(self, pusherdict):
|
||||||
if "data" in pusherdict and "brand" in pusherdict["data"]:
|
data = pusherdict["data"]
|
||||||
app_name = pusherdict["data"]["brand"]
|
|
||||||
else:
|
|
||||||
app_name = self.config.email_app_name
|
|
||||||
|
|
||||||
return app_name
|
if isinstance(data, dict):
|
||||||
|
brand = data.get("brand")
|
||||||
|
if isinstance(brand, str):
|
||||||
|
return brand
|
||||||
|
|
||||||
|
return self.config.email_app_name
|
||||||
|
|
|
@ -232,7 +232,6 @@ class PusherPool:
|
||||||
Deferred
|
Deferred
|
||||||
"""
|
"""
|
||||||
pushers = yield self.store.get_all_pushers()
|
pushers = yield self.store.get_all_pushers()
|
||||||
logger.info("Starting %d pushers", len(pushers))
|
|
||||||
|
|
||||||
# Stagger starting up the pushers so we don't completely drown the
|
# Stagger starting up the pushers so we don't completely drown the
|
||||||
# process on start up.
|
# process on start up.
|
||||||
|
@ -245,7 +244,7 @@ class PusherPool:
|
||||||
"""Start the given pusher
|
"""Start the given pusher
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
pusherdict (dict):
|
pusherdict (dict): dict with the values pulled from the db table
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Deferred[EmailPusher|HttpPusher]
|
Deferred[EmailPusher|HttpPusher]
|
||||||
|
@ -254,7 +253,8 @@ class PusherPool:
|
||||||
p = self.pusher_factory.create_pusher(pusherdict)
|
p = self.pusher_factory.create_pusher(pusherdict)
|
||||||
except PusherConfigException as e:
|
except PusherConfigException as e:
|
||||||
logger.warning(
|
logger.warning(
|
||||||
"Pusher incorrectly configured user=%s, appid=%s, pushkey=%s: %s",
|
"Pusher incorrectly configured id=%i, user=%s, appid=%s, pushkey=%s: %s",
|
||||||
|
pusherdict["id"],
|
||||||
pusherdict.get("user_name"),
|
pusherdict.get("user_name"),
|
||||||
pusherdict.get("app_id"),
|
pusherdict.get("app_id"),
|
||||||
pusherdict.get("pushkey"),
|
pusherdict.get("pushkey"),
|
||||||
|
@ -262,7 +262,9 @@ class PusherPool:
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.exception("Couldn't start a pusher: caught Exception")
|
logger.exception(
|
||||||
|
"Couldn't start pusher id %i: caught Exception", pusherdict["id"],
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
if not p:
|
if not p:
|
||||||
|
|
|
@ -28,6 +28,17 @@ from synapse.rest.client.v2_alpha._base import client_patterns
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
ALLOWED_KEYS = {
|
||||||
|
"app_display_name",
|
||||||
|
"app_id",
|
||||||
|
"data",
|
||||||
|
"device_display_name",
|
||||||
|
"kind",
|
||||||
|
"lang",
|
||||||
|
"profile_tag",
|
||||||
|
"pushkey",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class PushersRestServlet(RestServlet):
|
class PushersRestServlet(RestServlet):
|
||||||
PATTERNS = client_patterns("/pushers$", v1=True)
|
PATTERNS = client_patterns("/pushers$", v1=True)
|
||||||
|
@ -43,23 +54,11 @@ class PushersRestServlet(RestServlet):
|
||||||
|
|
||||||
pushers = await self.hs.get_datastore().get_pushers_by_user_id(user.to_string())
|
pushers = await self.hs.get_datastore().get_pushers_by_user_id(user.to_string())
|
||||||
|
|
||||||
allowed_keys = [
|
filtered_pushers = list(
|
||||||
"app_display_name",
|
{k: v for k, v in p.items() if k in ALLOWED_KEYS} for p in pushers
|
||||||
"app_id",
|
)
|
||||||
"data",
|
|
||||||
"device_display_name",
|
|
||||||
"kind",
|
|
||||||
"lang",
|
|
||||||
"profile_tag",
|
|
||||||
"pushkey",
|
|
||||||
]
|
|
||||||
|
|
||||||
for p in pushers:
|
return 200, {"pushers": filtered_pushers}
|
||||||
for k, v in list(p.items()):
|
|
||||||
if k not in allowed_keys:
|
|
||||||
del p[k]
|
|
||||||
|
|
||||||
return 200, {"pushers": pushers}
|
|
||||||
|
|
||||||
def on_OPTIONS(self, _):
|
def on_OPTIONS(self, _):
|
||||||
return 200, {}
|
return 200, {}
|
||||||
|
|
|
@ -15,8 +15,7 @@
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
from typing import Iterable, Iterator
|
||||||
import six
|
|
||||||
|
|
||||||
from canonicaljson import encode_canonical_json, json
|
from canonicaljson import encode_canonical_json, json
|
||||||
|
|
||||||
|
@ -27,21 +26,16 @@ from synapse.util.caches.descriptors import cachedInlineCallbacks, cachedList
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
if six.PY2:
|
|
||||||
db_binary_type = six.moves.builtins.buffer
|
|
||||||
else:
|
|
||||||
db_binary_type = memoryview
|
|
||||||
|
|
||||||
|
|
||||||
class PusherWorkerStore(SQLBaseStore):
|
class PusherWorkerStore(SQLBaseStore):
|
||||||
def _decode_pushers_rows(self, rows):
|
def _decode_pushers_rows(self, rows: Iterable[dict]) -> Iterator[dict]:
|
||||||
|
"""JSON-decode the data in the rows returned from the `pushers` table
|
||||||
|
|
||||||
|
Drops any rows whose data cannot be decoded
|
||||||
|
"""
|
||||||
for r in rows:
|
for r in rows:
|
||||||
dataJson = r["data"]
|
dataJson = r["data"]
|
||||||
r["data"] = None
|
|
||||||
try:
|
try:
|
||||||
if isinstance(dataJson, db_binary_type):
|
|
||||||
dataJson = str(dataJson).decode("UTF8")
|
|
||||||
|
|
||||||
r["data"] = json.loads(dataJson)
|
r["data"] = json.loads(dataJson)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(
|
logger.warning(
|
||||||
|
@ -50,12 +44,9 @@ class PusherWorkerStore(SQLBaseStore):
|
||||||
dataJson,
|
dataJson,
|
||||||
e.args[0],
|
e.args[0],
|
||||||
)
|
)
|
||||||
pass
|
continue
|
||||||
|
|
||||||
if isinstance(r["pushkey"], db_binary_type):
|
yield r
|
||||||
r["pushkey"] = str(r["pushkey"]).decode("UTF8")
|
|
||||||
|
|
||||||
return rows
|
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def user_has_pusher(self, user_id):
|
def user_has_pusher(self, user_id):
|
||||||
|
|
|
@ -165,6 +165,7 @@ class EmailPusherTests(HomeserverTestCase):
|
||||||
pushers = self.get_success(
|
pushers = self.get_success(
|
||||||
self.hs.get_datastore().get_pushers_by(dict(user_name=self.user_id))
|
self.hs.get_datastore().get_pushers_by(dict(user_name=self.user_id))
|
||||||
)
|
)
|
||||||
|
pushers = list(pushers)
|
||||||
self.assertEqual(len(pushers), 1)
|
self.assertEqual(len(pushers), 1)
|
||||||
last_stream_ordering = pushers[0]["last_stream_ordering"]
|
last_stream_ordering = pushers[0]["last_stream_ordering"]
|
||||||
|
|
||||||
|
@ -175,6 +176,7 @@ class EmailPusherTests(HomeserverTestCase):
|
||||||
pushers = self.get_success(
|
pushers = self.get_success(
|
||||||
self.hs.get_datastore().get_pushers_by(dict(user_name=self.user_id))
|
self.hs.get_datastore().get_pushers_by(dict(user_name=self.user_id))
|
||||||
)
|
)
|
||||||
|
pushers = list(pushers)
|
||||||
self.assertEqual(len(pushers), 1)
|
self.assertEqual(len(pushers), 1)
|
||||||
self.assertEqual(last_stream_ordering, pushers[0]["last_stream_ordering"])
|
self.assertEqual(last_stream_ordering, pushers[0]["last_stream_ordering"])
|
||||||
|
|
||||||
|
@ -192,5 +194,6 @@ class EmailPusherTests(HomeserverTestCase):
|
||||||
pushers = self.get_success(
|
pushers = self.get_success(
|
||||||
self.hs.get_datastore().get_pushers_by(dict(user_name=self.user_id))
|
self.hs.get_datastore().get_pushers_by(dict(user_name=self.user_id))
|
||||||
)
|
)
|
||||||
|
pushers = list(pushers)
|
||||||
self.assertEqual(len(pushers), 1)
|
self.assertEqual(len(pushers), 1)
|
||||||
self.assertTrue(pushers[0]["last_stream_ordering"] > last_stream_ordering)
|
self.assertTrue(pushers[0]["last_stream_ordering"] > last_stream_ordering)
|
||||||
|
|
|
@ -104,6 +104,7 @@ class HTTPPusherTests(HomeserverTestCase):
|
||||||
pushers = self.get_success(
|
pushers = self.get_success(
|
||||||
self.hs.get_datastore().get_pushers_by(dict(user_name=user_id))
|
self.hs.get_datastore().get_pushers_by(dict(user_name=user_id))
|
||||||
)
|
)
|
||||||
|
pushers = list(pushers)
|
||||||
self.assertEqual(len(pushers), 1)
|
self.assertEqual(len(pushers), 1)
|
||||||
last_stream_ordering = pushers[0]["last_stream_ordering"]
|
last_stream_ordering = pushers[0]["last_stream_ordering"]
|
||||||
|
|
||||||
|
@ -114,6 +115,7 @@ class HTTPPusherTests(HomeserverTestCase):
|
||||||
pushers = self.get_success(
|
pushers = self.get_success(
|
||||||
self.hs.get_datastore().get_pushers_by(dict(user_name=user_id))
|
self.hs.get_datastore().get_pushers_by(dict(user_name=user_id))
|
||||||
)
|
)
|
||||||
|
pushers = list(pushers)
|
||||||
self.assertEqual(len(pushers), 1)
|
self.assertEqual(len(pushers), 1)
|
||||||
self.assertEqual(last_stream_ordering, pushers[0]["last_stream_ordering"])
|
self.assertEqual(last_stream_ordering, pushers[0]["last_stream_ordering"])
|
||||||
|
|
||||||
|
@ -132,6 +134,7 @@ class HTTPPusherTests(HomeserverTestCase):
|
||||||
pushers = self.get_success(
|
pushers = self.get_success(
|
||||||
self.hs.get_datastore().get_pushers_by(dict(user_name=user_id))
|
self.hs.get_datastore().get_pushers_by(dict(user_name=user_id))
|
||||||
)
|
)
|
||||||
|
pushers = list(pushers)
|
||||||
self.assertEqual(len(pushers), 1)
|
self.assertEqual(len(pushers), 1)
|
||||||
self.assertTrue(pushers[0]["last_stream_ordering"] > last_stream_ordering)
|
self.assertTrue(pushers[0]["last_stream_ordering"] > last_stream_ordering)
|
||||||
last_stream_ordering = pushers[0]["last_stream_ordering"]
|
last_stream_ordering = pushers[0]["last_stream_ordering"]
|
||||||
|
@ -151,5 +154,6 @@ class HTTPPusherTests(HomeserverTestCase):
|
||||||
pushers = self.get_success(
|
pushers = self.get_success(
|
||||||
self.hs.get_datastore().get_pushers_by(dict(user_name=user_id))
|
self.hs.get_datastore().get_pushers_by(dict(user_name=user_id))
|
||||||
)
|
)
|
||||||
|
pushers = list(pushers)
|
||||||
self.assertEqual(len(pushers), 1)
|
self.assertEqual(len(pushers), 1)
|
||||||
self.assertTrue(pushers[0]["last_stream_ordering"] > last_stream_ordering)
|
self.assertTrue(pushers[0]["last_stream_ordering"] > last_stream_ordering)
|
||||||
|
|
Loading…
Reference in a new issue