Merge branch 'erikj-perf' of github.com:matrix-org/synapse into develop

pull/105/head
Erik Johnston 2015-01-06 14:45:57 +00:00
commit 8a12df8cf3
2 changed files with 54 additions and 26 deletions

View File

@ -16,7 +16,7 @@
from twisted.internet import defer from twisted.internet import defer
from synapse.api.errors import SynapseError, AuthError, CodeMessageException from synapse.api.errors import SynapseError, AuthError, CodeMessageException
from synapse.api.constants import Membership from synapse.api.constants import EventTypes, Membership
from synapse.util.logcontext import PreserveLoggingContext from synapse.util.logcontext import PreserveLoggingContext
from ._base import BaseHandler from ._base import BaseHandler
@ -203,7 +203,7 @@ class ProfileHandler(BaseHandler):
for j in joins: for j in joins:
content = { content = {
"membership": j.content["membership"], "membership": Membership.JOIN,
} }
yield self.distributor.fire( yield self.distributor.fire(
@ -212,9 +212,9 @@ class ProfileHandler(BaseHandler):
msg_handler = self.hs.get_handlers().message_handler msg_handler = self.hs.get_handlers().message_handler
yield msg_handler.create_and_send_event({ yield msg_handler.create_and_send_event({
"type": j.type, "type": EventTypes.Member,
"room_id": j.room_id, "room_id": j.room_id,
"state_key": j.state_key, "state_key": user.to_string(),
"content": content, "content": content,
"sender": j.state_key "sender": user.to_string()
}, ratelimit=False) }, ratelimit=False)

View File

@ -15,6 +15,8 @@
from twisted.internet import defer from twisted.internet import defer
from collections import namedtuple
from ._base import SQLBaseStore from ._base import SQLBaseStore
from synapse.api.constants import Membership from synapse.api.constants import Membership
@ -24,6 +26,12 @@ import logging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
RoomsForUser = namedtuple(
"RoomsForUser",
("room_id", "sender", "membership")
)
class RoomMemberStore(SQLBaseStore): class RoomMemberStore(SQLBaseStore):
def _store_room_member_txn(self, txn, event): def _store_room_member_txn(self, txn, event):
@ -163,19 +171,37 @@ class RoomMemberStore(SQLBaseStore):
membership_list (list): A list of synapse.api.constants.Membership membership_list (list): A list of synapse.api.constants.Membership
values which the user must be in. values which the user must be in.
Returns: Returns:
A list of RoomMemberEvent objects A list of dictionary objects, with room_id, membership and sender
defined.
""" """
if not membership_list: if not membership_list:
return defer.succeed(None) return defer.succeed(None)
args = [user_id]
args.extend(membership_list)
where_clause = "user_id = ? AND (%s)" % ( where_clause = "user_id = ? AND (%s)" % (
" OR ".join(["membership = ?" for _ in membership_list]), " OR ".join(["membership = ?" for _ in membership_list]),
) )
return self._get_members_query(where_clause, args) args = [user_id]
args.extend(membership_list)
def f(txn):
sql = (
"SELECT m.room_id, m.sender, m.membership"
" FROM room_memberships as m"
" INNER JOIN current_state_events as c"
" ON m.event_id = c.event_id"
" WHERE %s"
) % (where_clause,)
txn.execute(sql, args)
return [
RoomsForUser(**r) for r in self.cursor_to_dict(txn)
]
return self.runInteraction(
"get_rooms_for_user_where_membership_is",
f
)
def get_joined_hosts_for_room(self, room_id): def get_joined_hosts_for_room(self, room_id):
return self._simple_select_onecol( return self._simple_select_onecol(
@ -213,26 +239,28 @@ class RoomMemberStore(SQLBaseStore):
results = self._parse_events_txn(txn, rows) results = self._parse_events_txn(txn, rows)
return results return results
@defer.inlineCallbacks
def user_rooms_intersect(self, user_id_list): def user_rooms_intersect(self, user_id_list):
""" Checks whether all the users whose IDs are given in a list share a """ Checks whether all the users whose IDs are given in a list share a
room. room.
""" """
user_list_clause = " OR ".join(["m.user_id = ?"] * len(user_id_list)) def interaction(txn):
sql = ( user_list_clause = " OR ".join(["m.user_id = ?"] * len(user_id_list))
"SELECT m.room_id FROM room_memberships as m " sql = (
"INNER JOIN current_state_events as c " "SELECT m.room_id FROM room_memberships as m "
"ON m.event_id = c.event_id " "INNER JOIN current_state_events as c "
"WHERE m.membership = 'join' " "ON m.event_id = c.event_id "
"AND (%(clause)s) " "WHERE m.membership = 'join' "
# TODO(paul): We've got duplicate rows in the database somewhere "AND (%(clause)s) "
# so we have to DISTINCT m.user_id here # TODO(paul): We've got duplicate rows in the database somewhere
"GROUP BY m.room_id HAVING COUNT(DISTINCT m.user_id) = ?" # so we have to DISTINCT m.user_id here
) % {"clause": user_list_clause} "GROUP BY m.room_id HAVING COUNT(DISTINCT m.user_id) = ?"
) % {"clause": user_list_clause}
args = list(user_id_list) args = list(user_id_list)
args.append(len(user_id_list)) args.append(len(user_id_list))
rows = yield self._execute(None, sql, *args) txn.execute(sql, args)
defer.returnValue(len(rows) > 0) return len(txn.fetchall()) > 0
return self.runInteraction("user_rooms_intersect", interaction)