Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Commit

Permalink
make /context lazyload & filter aware (#3567)
Browse files Browse the repository at this point in the history
make /context lazyload & filter aware.
  • Loading branch information
ara4n authored Jul 27, 2018
1 parent b0b5566 commit e9b2d04
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 7 deletions.
1 change: 1 addition & 0 deletions changelog.d/3567.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
make the /context API filter & lazy-load aware as per MSC1227
24 changes: 21 additions & 3 deletions synapse/handlers/room.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
# limitations under the License.

"""Contains functions for performing events on rooms."""
import itertools
import logging
import math
import string
Expand Down Expand Up @@ -401,7 +402,7 @@ def __init__(self, hs):
self.store = hs.get_datastore()

@defer.inlineCallbacks
def get_event_context(self, user, room_id, event_id, limit):
def get_event_context(self, user, room_id, event_id, limit, event_filter):
"""Retrieves events, pagination tokens and state around a given event
in a room.
Expand All @@ -411,6 +412,8 @@ def get_event_context(self, user, room_id, event_id, limit):
event_id (str)
limit (int): The maximum number of events to return in total
(excluding state).
event_filter (Filter|None): the filter to apply to the events returned
(excluding the target event_id)
Returns:
dict, or None if the event isn't found
Expand Down Expand Up @@ -443,7 +446,7 @@ def filter_evts(events):
)

results = yield self.store.get_events_around(
room_id, event_id, before_limit, after_limit
room_id, event_id, before_limit, after_limit, event_filter
)

results["events_before"] = yield filter_evts(results["events_before"])
Expand All @@ -455,8 +458,23 @@ def filter_evts(events):
else:
last_event_id = event_id

types = None
filtered_types = None
if event_filter and event_filter.lazy_load_members():
members = set(ev.sender for ev in itertools.chain(
results["events_before"],
(results["event"],),
results["events_after"],
))
filtered_types = [EventTypes.Member]
types = [(EventTypes.Member, member) for member in members]

# XXX: why do we return the state as of the last event rather than the
# first? Shouldn't we be consistent with /sync?
# https://github.com/matrix-org/matrix-doc/issues/687

state = yield self.store.get_state_for_events(
[last_event_id], None
[last_event_id], types, filtered_types=filtered_types,
)
results["state"] = list(state[last_event_id].values())

Expand Down
2 changes: 1 addition & 1 deletion synapse/handlers/search.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ def search(self, user, content, batch=None):
contexts = {}
for event in allowed_events:
res = yield self.store.get_events_around(
event.room_id, event.event_id, before_limit, after_limit
event.room_id, event.event_id, before_limit, after_limit,
)

logger.info(
Expand Down
9 changes: 9 additions & 0 deletions synapse/rest/client/v1/room.py
Original file line number Diff line number Diff line change
Expand Up @@ -531,11 +531,20 @@ def on_GET(self, request, room_id, event_id):

limit = parse_integer(request, "limit", default=10)

# picking the API shape for symmetry with /messages
filter_bytes = parse_string(request, "filter")
if filter_bytes:
filter_json = urlparse.unquote(filter_bytes).decode("UTF-8")
event_filter = Filter(json.loads(filter_json))
else:
event_filter = None

results = yield self.room_context_handler.get_event_context(
requester.user,
room_id,
event_id,
limit,
event_filter,
)

if not results:
Expand Down
14 changes: 11 additions & 3 deletions synapse/storage/stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,9 @@ def _set_before_and_after(events, rows, topo_order=True):
)

@defer.inlineCallbacks
def get_events_around(self, room_id, event_id, before_limit, after_limit):
def get_events_around(
self, room_id, event_id, before_limit, after_limit, event_filter=None,
):
"""Retrieve events and pagination tokens around a given event in a
room.
Expand All @@ -536,14 +538,15 @@ def get_events_around(self, room_id, event_id, before_limit, after_limit):
event_id (str)
before_limit (int)
after_limit (int)
event_filter (Filter|None)
Returns:
dict
"""

results = yield self.runInteraction(
"get_events_around", self._get_events_around_txn,
room_id, event_id, before_limit, after_limit
room_id, event_id, before_limit, after_limit, event_filter,
)

events_before = yield self._get_events(
Expand All @@ -563,7 +566,9 @@ def get_events_around(self, room_id, event_id, before_limit, after_limit):
"end": results["after"]["token"],
})

def _get_events_around_txn(self, txn, room_id, event_id, before_limit, after_limit):
def _get_events_around_txn(
self, txn, room_id, event_id, before_limit, after_limit, event_filter,
):
"""Retrieves event_ids and pagination tokens around a given event in a
room.
Expand All @@ -572,6 +577,7 @@ def _get_events_around_txn(self, txn, room_id, event_id, before_limit, after_lim
event_id (str)
before_limit (int)
after_limit (int)
event_filter (Filter|None)
Returns:
dict
Expand Down Expand Up @@ -601,11 +607,13 @@ def _get_events_around_txn(self, txn, room_id, event_id, before_limit, after_lim

rows, start_token = self._paginate_room_events_txn(
txn, room_id, before_token, direction='b', limit=before_limit,
event_filter=event_filter,
)
events_before = [r.event_id for r in rows]

rows, end_token = self._paginate_room_events_txn(
txn, room_id, after_token, direction='f', limit=after_limit,
event_filter=event_filter,
)
events_after = [r.event_id for r in rows]

Expand Down

0 comments on commit e9b2d04

Please sign in to comment.