forked from MirrorHub/synapse
parent
bc5589a1bb
commit
329ef5c715
6 changed files with 93 additions and 27 deletions
1
changelog.d/10279.bugfix
Normal file
1
changelog.d/10279.bugfix
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Fix the prometheus `synapse_federation_server_pdu_process_time` metric. Broke in v1.37.1.
|
|
@ -369,7 +369,6 @@ class FederationServer(FederationBase):
|
||||||
|
|
||||||
async def process_pdu(pdu: EventBase) -> JsonDict:
|
async def process_pdu(pdu: EventBase) -> JsonDict:
|
||||||
event_id = pdu.event_id
|
event_id = pdu.event_id
|
||||||
with pdu_process_time.time():
|
|
||||||
with nested_logging_context(event_id):
|
with nested_logging_context(event_id):
|
||||||
try:
|
try:
|
||||||
await self._handle_received_pdu(origin, pdu)
|
await self._handle_received_pdu(origin, pdu)
|
||||||
|
@ -932,9 +931,13 @@ class FederationServer(FederationBase):
|
||||||
exc_info=(f.type, f.value, f.getTracebackObject()), # type: ignore
|
exc_info=(f.type, f.value, f.getTracebackObject()), # type: ignore
|
||||||
)
|
)
|
||||||
|
|
||||||
await self.store.remove_received_event_from_staging(
|
received_ts = await self.store.remove_received_event_from_staging(
|
||||||
origin, event.event_id
|
origin, event.event_id
|
||||||
)
|
)
|
||||||
|
if received_ts is not None:
|
||||||
|
pdu_process_time.observe(
|
||||||
|
(self._clock.time_msec() - received_ts) / 1000
|
||||||
|
)
|
||||||
|
|
||||||
# We need to do this check outside the lock to avoid a race between
|
# We need to do this check outside the lock to avoid a race between
|
||||||
# a new event being inserted by another instance and it attempting
|
# a new event being inserted by another instance and it attempting
|
||||||
|
|
|
@ -1075,15 +1075,61 @@ class EventFederationWorkerStore(EventsWorkerStore, SignatureWorkerStore, SQLBas
|
||||||
self,
|
self,
|
||||||
origin: str,
|
origin: str,
|
||||||
event_id: str,
|
event_id: str,
|
||||||
) -> None:
|
) -> Optional[int]:
|
||||||
"""Remove the given event from the staging area"""
|
"""Remove the given event from the staging area.
|
||||||
await self.db_pool.simple_delete(
|
|
||||||
|
Returns:
|
||||||
|
The received_ts of the row that was deleted, if any.
|
||||||
|
"""
|
||||||
|
if self.db_pool.engine.supports_returning:
|
||||||
|
|
||||||
|
def _remove_received_event_from_staging_txn(txn):
|
||||||
|
sql = """
|
||||||
|
DELETE FROM federation_inbound_events_staging
|
||||||
|
WHERE origin = ? AND event_id = ?
|
||||||
|
RETURNING received_ts
|
||||||
|
"""
|
||||||
|
|
||||||
|
txn.execute(sql, (origin, event_id))
|
||||||
|
return txn.fetchone()
|
||||||
|
|
||||||
|
row = await self.db_pool.runInteraction(
|
||||||
|
"remove_received_event_from_staging",
|
||||||
|
_remove_received_event_from_staging_txn,
|
||||||
|
db_autocommit=True,
|
||||||
|
)
|
||||||
|
if row is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return row[0]
|
||||||
|
|
||||||
|
else:
|
||||||
|
|
||||||
|
def _remove_received_event_from_staging_txn(txn):
|
||||||
|
received_ts = self.db_pool.simple_select_one_onecol_txn(
|
||||||
|
txn,
|
||||||
table="federation_inbound_events_staging",
|
table="federation_inbound_events_staging",
|
||||||
keyvalues={
|
keyvalues={
|
||||||
"origin": origin,
|
"origin": origin,
|
||||||
"event_id": event_id,
|
"event_id": event_id,
|
||||||
},
|
},
|
||||||
desc="remove_received_event_from_staging",
|
retcol="received_ts",
|
||||||
|
allow_none=True,
|
||||||
|
)
|
||||||
|
self.db_pool.simple_delete_txn(
|
||||||
|
txn,
|
||||||
|
table="federation_inbound_events_staging",
|
||||||
|
keyvalues={
|
||||||
|
"origin": origin,
|
||||||
|
"event_id": event_id,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
return received_ts
|
||||||
|
|
||||||
|
return await self.db_pool.runInteraction(
|
||||||
|
"remove_received_event_from_staging",
|
||||||
|
_remove_received_event_from_staging_txn,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def get_next_staged_event_id_for_room(
|
async def get_next_staged_event_id_for_room(
|
||||||
|
|
|
@ -49,6 +49,12 @@ class BaseDatabaseEngine(Generic[ConnectionType], metaclass=abc.ABCMeta):
|
||||||
"""
|
"""
|
||||||
...
|
...
|
||||||
|
|
||||||
|
@property
|
||||||
|
@abc.abstractmethod
|
||||||
|
def supports_returning(self) -> bool:
|
||||||
|
"""Do we support the `RETURNING` clause in insert/update/delete?"""
|
||||||
|
...
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def check_database(
|
def check_database(
|
||||||
self, db_conn: ConnectionType, allow_outdated_version: bool = False
|
self, db_conn: ConnectionType, allow_outdated_version: bool = False
|
||||||
|
|
|
@ -133,6 +133,11 @@ class PostgresEngine(BaseDatabaseEngine):
|
||||||
"""Do we support using `a = ANY(?)` and passing a list"""
|
"""Do we support using `a = ANY(?)` and passing a list"""
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@property
|
||||||
|
def supports_returning(self) -> bool:
|
||||||
|
"""Do we support the `RETURNING` clause in insert/update/delete?"""
|
||||||
|
return True
|
||||||
|
|
||||||
def is_deadlock(self, error):
|
def is_deadlock(self, error):
|
||||||
if isinstance(error, self.module.DatabaseError):
|
if isinstance(error, self.module.DatabaseError):
|
||||||
# https://www.postgresql.org/docs/current/static/errcodes-appendix.html
|
# https://www.postgresql.org/docs/current/static/errcodes-appendix.html
|
||||||
|
|
|
@ -60,6 +60,11 @@ class Sqlite3Engine(BaseDatabaseEngine["sqlite3.Connection"]):
|
||||||
"""Do we support using `a = ANY(?)` and passing a list"""
|
"""Do we support using `a = ANY(?)` and passing a list"""
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@property
|
||||||
|
def supports_returning(self) -> bool:
|
||||||
|
"""Do we support the `RETURNING` clause in insert/update/delete?"""
|
||||||
|
return self.module.sqlite_version_info >= (3, 35, 0)
|
||||||
|
|
||||||
def check_database(self, db_conn, allow_outdated_version: bool = False):
|
def check_database(self, db_conn, allow_outdated_version: bool = False):
|
||||||
if not allow_outdated_version:
|
if not allow_outdated_version:
|
||||||
version = self.module.sqlite_version_info
|
version = self.module.sqlite_version_info
|
||||||
|
|
Loading…
Reference in a new issue