-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Federation Sender & Appservice Pusher Stream Optimisations #13251
Changes from 5 commits
b42c899
9910139
49581d7
45157fa
b1f11cc
c59d717
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Optimise federation sender and appservice pusher event stream processing queries. Contributed by Nick @ Beeper (@fizzadar). |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -371,52 +371,22 @@ def _get_oldest_unsent_txn( | |||||
device_list_summary=DeviceListUpdates(), | ||||||
) | ||||||
|
||||||
async def set_appservice_last_pos(self, pos: int) -> None: | ||||||
def set_appservice_last_pos_txn(txn: LoggingTransaction) -> None: | ||||||
txn.execute( | ||||||
"UPDATE appservice_stream_position SET stream_ordering = ?", (pos,) | ||||||
) | ||||||
|
||||||
await self.db_pool.runInteraction( | ||||||
"set_appservice_last_pos", set_appservice_last_pos_txn | ||||||
async def get_appservice_last_pos(self) -> int: | ||||||
return await self.db_pool.simple_select_one_onecol( | ||||||
table="appservice_stream_position", | ||||||
retcol="stream_ordering", | ||||||
keyvalues={}, | ||||||
desc="get_appservice_last_pos_txn", | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. generally we don't include
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah makes sense, noted for future! Fixed via c59d717 |
||||||
) | ||||||
|
||||||
async def get_new_events_for_appservice( | ||||||
self, current_id: int, limit: int | ||||||
) -> Tuple[int, List[EventBase]]: | ||||||
"""Get all new events for an appservice""" | ||||||
|
||||||
def get_new_events_for_appservice_txn( | ||||||
txn: LoggingTransaction, | ||||||
) -> Tuple[int, List[str]]: | ||||||
sql = ( | ||||||
"SELECT e.stream_ordering, e.event_id" | ||||||
" FROM events AS e" | ||||||
" WHERE" | ||||||
" (SELECT stream_ordering FROM appservice_stream_position)" | ||||||
" < e.stream_ordering" | ||||||
" AND e.stream_ordering <= ?" | ||||||
" ORDER BY e.stream_ordering ASC" | ||||||
" LIMIT ?" | ||||||
) | ||||||
|
||||||
txn.execute(sql, (current_id, limit)) | ||||||
rows = txn.fetchall() | ||||||
|
||||||
upper_bound = current_id | ||||||
if len(rows) == limit: | ||||||
upper_bound = rows[-1][0] | ||||||
|
||||||
return upper_bound, [row[1] for row in rows] | ||||||
|
||||||
upper_bound, event_ids = await self.db_pool.runInteraction( | ||||||
"get_new_events_for_appservice", get_new_events_for_appservice_txn | ||||||
async def set_appservice_last_pos(self, pos: int) -> None: | ||||||
await self.db_pool.simple_update_one( | ||||||
table="appservice_stream_position", | ||||||
keyvalues={}, | ||||||
updatevalues={"stream_ordering": pos}, | ||||||
desc="set_appservice_last_pos_txn", | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. any reason not to stick with the old description?
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Whoops typo'd! Fixed in c59d717 |
||||||
) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Am I right in thinking that this rewrite of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep just switched to the simple query versions for consistency elsewhere, no functional change. |
||||||
|
||||||
events = await self.get_events_as_list(event_ids, get_prev_content=True) | ||||||
|
||||||
return upper_bound, events | ||||||
|
||||||
async def get_type_stream_id_for_appservice( | ||||||
self, service: ApplicationService, type: str | ||||||
) -> int: | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1022,8 +1022,8 @@ def _get_events_around_txn( | |
} | ||
|
||
async def get_all_new_events_stream( | ||
self, from_id: int, current_id: int, limit: int | ||
) -> Tuple[int, List[EventBase]]: | ||
self, from_id: int, current_id: int, limit: int, get_prev_content: bool = False | ||
) -> Tuple[int, List[EventBase], Dict[str, Optional[int]]]: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please update the docstring! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
"""Get all new events | ||
|
||
Returns all events with from_id < stream_ordering <= current_id. | ||
|
@@ -1042,9 +1042,9 @@ async def get_all_new_events_stream( | |
|
||
def get_all_new_events_stream_txn( | ||
txn: LoggingTransaction, | ||
) -> Tuple[int, List[str]]: | ||
) -> Tuple[int, Dict[str, Optional[int]]]: | ||
sql = ( | ||
"SELECT e.stream_ordering, e.event_id" | ||
"SELECT e.stream_ordering, e.event_id, e.received_ts" | ||
" FROM events AS e" | ||
" WHERE" | ||
" ? < e.stream_ordering AND e.stream_ordering <= ?" | ||
|
@@ -1059,15 +1059,21 @@ def get_all_new_events_stream_txn( | |
if len(rows) == limit: | ||
upper_bound = rows[-1][0] | ||
|
||
return upper_bound, [row[1] for row in rows] | ||
event_to_received_ts: Dict[str, Optional[int]] = { | ||
row[1]: row[2] for row in rows | ||
} | ||
return upper_bound, event_to_received_ts | ||
|
||
upper_bound, event_ids = await self.db_pool.runInteraction( | ||
upper_bound, event_to_received_ts = await self.db_pool.runInteraction( | ||
"get_all_new_events_stream", get_all_new_events_stream_txn | ||
) | ||
|
||
events = await self.get_events_as_list(event_ids) | ||
events = await self.get_events_as_list( | ||
event_to_received_ts.keys(), | ||
get_prev_content=get_prev_content, | ||
) | ||
|
||
return upper_bound, events | ||
return upper_bound, events, event_to_received_ts | ||
|
||
async def get_federation_out_pos(self, typ: str) -> int: | ||
if self._need_to_reset_federation_stream_positions: | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please could you give this a docstring?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added in c59d717