mirror of
https://git.anonymousland.org/anonymousland/synapse-product.git
synced 2024-09-08 05:41:57 +00:00
Fix incredubly slow back pagination query
If a client didn't specify a from token when paginating backwards synapse would attempt to query the (global) maximum topological token. This a) doesn't make much sense since they're room specific and b) there are no indices that lets postgres do this efficiently.
This commit is contained in:
parent
a842fed418
commit
d04e2ff3a4
@ -82,8 +82,8 @@ class MessageHandler(BaseHandler):
|
|||||||
room_token = pagin_config.from_token.room_key
|
room_token = pagin_config.from_token.room_key
|
||||||
else:
|
else:
|
||||||
pagin_config.from_token = (
|
pagin_config.from_token = (
|
||||||
yield self.hs.get_event_sources().get_current_token(
|
yield self.hs.get_event_sources().get_current_token_for_room(
|
||||||
direction='b'
|
room_id=room_id
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
room_token = pagin_config.from_token.room_key
|
room_token = pagin_config.from_token.room_key
|
||||||
|
@ -475,8 +475,11 @@ class RoomEventSource(object):
|
|||||||
|
|
||||||
defer.returnValue((events, end_key))
|
defer.returnValue((events, end_key))
|
||||||
|
|
||||||
def get_current_key(self, direction='f'):
|
def get_current_key(self):
|
||||||
return self.store.get_room_events_max_id(direction)
|
return self.store.get_room_events_max_id()
|
||||||
|
|
||||||
|
def get_current_key_for_room(self, room_id):
|
||||||
|
return self.store.get_room_events_max_id(room_id)
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def get_pagination_rows(self, user, config, key):
|
def get_pagination_rows(self, user, config, key):
|
||||||
|
@ -521,13 +521,20 @@ class StreamStore(SQLBaseStore):
|
|||||||
)
|
)
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def get_room_events_max_id(self, direction='f'):
|
def get_room_events_max_id(self, room_id=None):
|
||||||
|
"""Returns the current token for rooms stream.
|
||||||
|
|
||||||
|
By default, it returns the current global stream token. Specifying a
|
||||||
|
`room_id` causes it to return the current room specific topological
|
||||||
|
token.
|
||||||
|
"""
|
||||||
token = yield self._stream_id_gen.get_current_token()
|
token = yield self._stream_id_gen.get_current_token()
|
||||||
if direction != 'b':
|
if room_id is None:
|
||||||
defer.returnValue("s%d" % (token,))
|
defer.returnValue("s%d" % (token,))
|
||||||
else:
|
else:
|
||||||
topo = yield self.runInteraction(
|
topo = yield self.runInteraction(
|
||||||
"_get_max_topological_txn", self._get_max_topological_txn
|
"_get_max_topological_txn", self._get_max_topological_txn,
|
||||||
|
room_id,
|
||||||
)
|
)
|
||||||
defer.returnValue("t%d-%d" % (topo, token))
|
defer.returnValue("t%d-%d" % (topo, token))
|
||||||
|
|
||||||
@ -579,11 +586,11 @@ class StreamStore(SQLBaseStore):
|
|||||||
lambda r: r[0][0] if r else 0
|
lambda r: r[0][0] if r else 0
|
||||||
)
|
)
|
||||||
|
|
||||||
def _get_max_topological_txn(self, txn):
|
def _get_max_topological_txn(self, txn, room_id):
|
||||||
txn.execute(
|
txn.execute(
|
||||||
"SELECT MAX(topological_ordering) FROM events"
|
"SELECT MAX(topological_ordering) FROM events"
|
||||||
" WHERE outlier = ?",
|
" WHERE room_id = ?",
|
||||||
(False,)
|
(room_id,)
|
||||||
)
|
)
|
||||||
|
|
||||||
rows = txn.fetchall()
|
rows = txn.fetchall()
|
||||||
|
@ -41,13 +41,39 @@ class EventSources(object):
|
|||||||
self.store = hs.get_datastore()
|
self.store = hs.get_datastore()
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def get_current_token(self, direction='f'):
|
def get_current_token(self):
|
||||||
push_rules_key, _ = self.store.get_push_rules_stream_token()
|
push_rules_key, _ = self.store.get_push_rules_stream_token()
|
||||||
to_device_key = self.store.get_to_device_stream_token()
|
to_device_key = self.store.get_to_device_stream_token()
|
||||||
|
|
||||||
token = StreamToken(
|
token = StreamToken(
|
||||||
room_key=(
|
room_key=(
|
||||||
yield self.sources["room"].get_current_key(direction)
|
yield self.sources["room"].get_current_key()
|
||||||
|
),
|
||||||
|
presence_key=(
|
||||||
|
yield self.sources["presence"].get_current_key()
|
||||||
|
),
|
||||||
|
typing_key=(
|
||||||
|
yield self.sources["typing"].get_current_key()
|
||||||
|
),
|
||||||
|
receipt_key=(
|
||||||
|
yield self.sources["receipt"].get_current_key()
|
||||||
|
),
|
||||||
|
account_data_key=(
|
||||||
|
yield self.sources["account_data"].get_current_key()
|
||||||
|
),
|
||||||
|
push_rules_key=push_rules_key,
|
||||||
|
to_device_key=to_device_key,
|
||||||
|
)
|
||||||
|
defer.returnValue(token)
|
||||||
|
|
||||||
|
@defer.inlineCallbacks
|
||||||
|
def get_current_token_for_room(self, room_id):
|
||||||
|
push_rules_key, _ = self.store.get_push_rules_stream_token()
|
||||||
|
to_device_key = self.store.get_to_device_stream_token()
|
||||||
|
|
||||||
|
token = StreamToken(
|
||||||
|
room_key=(
|
||||||
|
yield self.sources["room"].get_current_key()
|
||||||
),
|
),
|
||||||
presence_key=(
|
presence_key=(
|
||||||
yield self.sources["presence"].get_current_key()
|
yield self.sources["presence"].get_current_key()
|
||||||
|
Loading…
Reference in New Issue
Block a user