switch to named tuple

This commit is contained in:
Matthew Hodgson 2018-09-07 23:49:05 +01:00
parent 967fdfef10
commit c39754aac2
2 changed files with 48 additions and 27 deletions

View file

@ -32,6 +32,7 @@ from synapse.util.caches.response_cache import ResponseCache
from synapse.util.logcontext import LoggingContext from synapse.util.logcontext import LoggingContext
from synapse.util.metrics import Measure, measure_func from synapse.util.metrics import Measure, measure_func
from synapse.visibility import filter_events_for_client from synapse.visibility import filter_events_for_client
from synapse.storage.roommember import MemberSummary
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -551,27 +552,28 @@ class SyncHandler(object):
canonical_alias_id = state_ids.get((EventTypes.CanonicalAlias, '')) canonical_alias_id = state_ids.get((EventTypes.CanonicalAlias, ''))
summary = {} summary = {}
empty_ms = MemberSummary([], 0)
# TODO: only send these when they change. # TODO: only send these when they change.
summary["m.joined_member_count"] = ( summary["m.joined_member_count"] = (
details.get(Membership.JOIN, ([], 0))[1] details.get(Membership.JOIN, empty_ms).count
) )
summary["m.invited_member_count"] = ( summary["m.invited_member_count"] = (
details.get(Membership.INVITE, ([], 0))[1] details.get(Membership.INVITE, empty_ms).count
) )
if name_id or canonical_alias_id: if name_id or canonical_alias_id:
defer.returnValue(summary) defer.returnValue(summary)
joined_user_ids = [ joined_user_ids = [
r[0] for r in details.get(Membership.JOIN, ([], 0))[0] r[0] for r in details.get(Membership.JOIN, empty_ms).members
] ]
invited_user_ids = [ invited_user_ids = [
r[0] for r in details.get(Membership.INVITE, ([], 0))[0] r[0] for r in details.get(Membership.INVITE, empty_ms).members
] ]
gone_user_ids = ( gone_user_ids = (
[r[0] for r in details.get(Membership.LEAVE, ([], 0))[0]] + [r[0] for r in details.get(Membership.LEAVE, empty_ms).members] +
[r[0] for r in details.get(Membership.BAN, ([], 0))[0]] [r[0] for r in details.get(Membership.BAN, empty_ms).members]
) )
# FIXME: only build up a member_ids list for our heroes # FIXME: only build up a member_ids list for our heroes

View file

@ -51,6 +51,12 @@ ProfileInfo = namedtuple(
"ProfileInfo", ("avatar_url", "display_name") "ProfileInfo", ("avatar_url", "display_name")
) )
# "members" points to a truncated list of (user_id, event_id) tuples for users of
# a given membership type, suitable for use in calculating heroes for a room.
# "count" points to the total numberr of users of a given membership type.
MemberSummary = namedtuple(
"MemberSummary", ("members", "count")
)
_MEMBERSHIP_PROFILE_UPDATE_NAME = "room_membership_profile_update" _MEMBERSHIP_PROFILE_UPDATE_NAME = "room_membership_profile_update"
@ -84,9 +90,37 @@ class RoomMemberWorkerStore(EventsWorkerStore):
@cached(max_entries=100000, iterable=True) @cached(max_entries=100000, iterable=True)
def get_room_summary(self, room_id): def get_room_summary(self, room_id):
""" Get the details of a room roughly suitable for use by the room
summary extension to /sync. Useful when lazy loading room members.
Args:
room_id (str): The room ID to query
Returns:
Deferred[dict[str, MemberSummary]:
dict of membership states, pointing to a MemberSummary named tuple.
"""
def f(txn): def f(txn):
# first get counts.
# We do this all in one transaction to keep the cache small.
# FIXME: get rid of this when we have room_stats
sql = ( sql = (
"SELECT m.user_id, m.membership, m.event_id FROM room_memberships as m" "SELECT count(*), m.membership FROM room_memberships as m"
" INNER JOIN current_state_events as c"
" ON m.event_id = c.event_id"
" AND m.room_id = c.room_id"
" AND m.user_id = c.state_key"
" WHERE c.type = 'm.room.member' AND c.room_id = ?"
" GROUP BY m.membership"
)
txn.execute(sql, (room_id,))
res = {}
for r in txn:
summary = res.setdefault(to_ascii(r[1]), MemberSummary([], r[0]))
sql = (
"SELECT m.user_id, m.membership, m.event_id "
"FROM room_memberships as m"
" INNER JOIN current_state_events as c" " INNER JOIN current_state_events as c"
" ON m.event_id = c.event_id" " ON m.event_id = c.event_id"
" AND m.room_id = c.room_id" " AND m.room_id = c.room_id"
@ -95,25 +129,10 @@ class RoomMemberWorkerStore(EventsWorkerStore):
) )
txn.execute(sql, (room_id, 5)) txn.execute(sql, (room_id, 5))
res = {}
for r in txn: for r in txn:
summary = res.setdefault(to_ascii(r[1]), {}) summary = res.get(to_ascii(r[1]))
users = summary.setdefault('users', []) members = summary.members
users.append((to_ascii(r[0]), to_ascii(r[2]))) members.append((to_ascii(r[0]), to_ascii(r[2])))
sql = (
"SELECT count(*), m.membership FROM room_memberships as m"
" INNER JOIN current_state_events as c"
" ON m.event_id = c.event_id "
" AND m.room_id = c.room_id "
" AND m.user_id = c.state_key"
" WHERE c.type = 'm.room.member' AND c.room_id = ? group by m.membership"
)
txn.execute(sql, (room_id,))
for r in txn:
summary = res.setdefault(to_ascii(r[1]), {})
summary['count'] = r[0]
return res return res