mirror of
https://git.anonymousland.org/anonymousland/synapse.git
synced 2024-10-01 11:49:51 -04:00
Fix federation stall on concurrent access errors (#9639)
This commit is contained in:
parent
4ecba9bd5c
commit
0caf2a338e
1
changelog.d/9639.bugfix
Normal file
1
changelog.d/9639.bugfix
Normal file
@ -0,0 +1 @@
|
|||||||
|
Fix bug where federation sending can stall due to `concurrent access` database exceptions when it falls behind.
|
@ -22,7 +22,6 @@ from canonicaljson import encode_canonical_json
|
|||||||
from synapse.metrics.background_process_metrics import wrap_as_background_process
|
from synapse.metrics.background_process_metrics import wrap_as_background_process
|
||||||
from synapse.storage._base import SQLBaseStore, db_to_json
|
from synapse.storage._base import SQLBaseStore, db_to_json
|
||||||
from synapse.storage.database import DatabasePool, LoggingTransaction
|
from synapse.storage.database import DatabasePool, LoggingTransaction
|
||||||
from synapse.storage.engines import PostgresEngine, Sqlite3Engine
|
|
||||||
from synapse.types import JsonDict
|
from synapse.types import JsonDict
|
||||||
from synapse.util.caches.expiringcache import ExpiringCache
|
from synapse.util.caches.expiringcache import ExpiringCache
|
||||||
|
|
||||||
@ -312,49 +311,23 @@ class TransactionStore(TransactionWorkerStore):
|
|||||||
stream_ordering: the stream_ordering of the event
|
stream_ordering: the stream_ordering of the event
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return await self.db_pool.runInteraction(
|
await self.db_pool.simple_upsert_many(
|
||||||
"store_destination_rooms_entries",
|
table="destinations",
|
||||||
self._store_destination_rooms_entries_txn,
|
key_names=("destination",),
|
||||||
destinations,
|
key_values=[(d,) for d in destinations],
|
||||||
room_id,
|
value_names=[],
|
||||||
stream_ordering,
|
value_values=[],
|
||||||
|
desc="store_destination_rooms_entries_dests",
|
||||||
)
|
)
|
||||||
|
|
||||||
def _store_destination_rooms_entries_txn(
|
|
||||||
self,
|
|
||||||
txn: LoggingTransaction,
|
|
||||||
destinations: Iterable[str],
|
|
||||||
room_id: str,
|
|
||||||
stream_ordering: int,
|
|
||||||
) -> None:
|
|
||||||
|
|
||||||
# ensure we have a `destinations` row for this destination, as there is
|
|
||||||
# a foreign key constraint.
|
|
||||||
if isinstance(self.database_engine, PostgresEngine):
|
|
||||||
q = """
|
|
||||||
INSERT INTO destinations (destination)
|
|
||||||
VALUES (?)
|
|
||||||
ON CONFLICT DO NOTHING;
|
|
||||||
"""
|
|
||||||
elif isinstance(self.database_engine, Sqlite3Engine):
|
|
||||||
q = """
|
|
||||||
INSERT OR IGNORE INTO destinations (destination)
|
|
||||||
VALUES (?);
|
|
||||||
"""
|
|
||||||
else:
|
|
||||||
raise RuntimeError("Unknown database engine")
|
|
||||||
|
|
||||||
txn.execute_batch(q, ((destination,) for destination in destinations))
|
|
||||||
|
|
||||||
rows = [(destination, room_id) for destination in destinations]
|
rows = [(destination, room_id) for destination in destinations]
|
||||||
|
await self.db_pool.simple_upsert_many(
|
||||||
self.db_pool.simple_upsert_many_txn(
|
|
||||||
txn,
|
|
||||||
table="destination_rooms",
|
table="destination_rooms",
|
||||||
key_names=("destination", "room_id"),
|
key_names=("destination", "room_id"),
|
||||||
key_values=rows,
|
key_values=rows,
|
||||||
value_names=["stream_ordering"],
|
value_names=["stream_ordering"],
|
||||||
value_values=[(stream_ordering,)] * len(rows),
|
value_values=[(stream_ordering,)] * len(rows),
|
||||||
|
desc="store_destination_rooms_entries_rooms",
|
||||||
)
|
)
|
||||||
|
|
||||||
async def get_destination_last_successful_stream_ordering(
|
async def get_destination_last_successful_stream_ordering(
|
||||||
|
Loading…
Reference in New Issue
Block a user