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

Send down device list change notif when member leaves/rejoins room #2443

Merged
merged 7 commits into from
Sep 18, 2017
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion synapse/handlers/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ def get_user_ids_changed(self, user_id, from_token):

# check if this member has changed since any of the extremities
# at the stream_ordering, and add them to the list if so.
for state_dict in prev_state_ids.values():
for state_dict in prev_state_ids.itervalues():
prev_event_id = state_dict.get(key, None)
if not prev_event_id or prev_event_id != event_id:
possibly_changed.add(state_key)
Expand Down
64 changes: 52 additions & 12 deletions synapse/handlers/sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,16 @@ def __nonzero__(self):
return True


class DeviceLists(collections.namedtuple("DeviceLists", [
"changed", # list of user_ids whose devices may have changed
"left", # list of user_ids whose devices we no longer track
])):
__slots__ = []

def __nonzero__(self):
return bool(self.changed or self.left)


class SyncResult(collections.namedtuple("SyncResult", [
"next_batch", # Token for the next sync
"presence", # List of presence events for the user.
Expand Down Expand Up @@ -535,7 +545,7 @@ def generate_sync_result(self, sync_config, since_token=None, full_state=False):
res = yield self._generate_sync_entry_for_rooms(
sync_result_builder, account_data_by_room
)
newly_joined_rooms, newly_joined_users = res
newly_joined_rooms, newly_joined_users, _, newly_left_users = res

block_all_presence_data = (
since_token is None and
Expand All @@ -549,7 +559,11 @@ def generate_sync_result(self, sync_config, since_token=None, full_state=False):
yield self._generate_sync_entry_for_to_device(sync_result_builder)

device_lists = yield self._generate_sync_entry_for_device_list(
sync_result_builder
sync_result_builder,
newly_joined_rooms=newly_joined_rooms,
newly_joined_users=newly_joined_users,
newly_left_rooms=[],
newly_left_users=newly_left_users,
)

device_id = sync_config.device_id
Expand All @@ -574,24 +588,42 @@ def generate_sync_result(self, sync_config, since_token=None, full_state=False):

@measure_func("_generate_sync_entry_for_device_list")
@defer.inlineCallbacks
def _generate_sync_entry_for_device_list(self, sync_result_builder):
def _generate_sync_entry_for_device_list(self, sync_result_builder,
newly_joined_rooms, newly_joined_users,
newly_left_rooms, newly_left_users):
user_id = sync_result_builder.sync_config.user.to_string()
since_token = sync_result_builder.since_token

if since_token and since_token.device_list_key:
changed = yield self.store.get_user_whose_devices_changed(
since_token.device_list_key
)
if not changed:
defer.returnValue([])

# TODO: Check that these users are actually new, i.e. either they
# weren't in the previous sync *or* they left and rejoined.
changed.update(newly_joined_users)

# TODO: Add the members from newly_*_rooms

if not changed and not newly_left_users:
defer.returnValue(DeviceLists(
changed=[],
left=newly_left_users,
))

users_who_share_room = yield self.store.get_users_who_share_room_with_user(
user_id
)

defer.returnValue(users_who_share_room & changed)
defer.returnValue(DeviceLists(
changed=users_who_share_room & changed,
left=set(newly_left_users) - users_who_share_room,
))
else:
defer.returnValue([])
defer.returnValue(DeviceLists(
changed=[],
left=[],
))

@defer.inlineCallbacks
def _generate_sync_entry_for_to_device(self, sync_result_builder):
Expand Down Expand Up @@ -755,8 +787,8 @@ def _generate_sync_entry_for_rooms(self, sync_result_builder, account_data_by_ro
account_data_by_room(dict): Dictionary of per room account data

Returns:
Deferred(tuple): Returns a 2-tuple of
`(newly_joined_rooms, newly_joined_users)`
Deferred(tuple): Returns a 4-tuple of
`(newly_joined_rooms, newly_joined_users, newly_left_rooms, newly_left_users)`
"""
user_id = sync_result_builder.sync_config.user.to_string()
block_all_room_ephemeral = (
Expand Down Expand Up @@ -787,7 +819,7 @@ def _generate_sync_entry_for_rooms(self, sync_result_builder, account_data_by_ro
)
if not tags_by_room:
logger.debug("no-oping sync")
defer.returnValue(([], []))
defer.returnValue(([], [], [], []))

ignored_account_data = yield self.store.get_global_account_data_by_type_for_user(
"m.ignored_user_list", user_id=user_id,
Expand Down Expand Up @@ -828,17 +860,24 @@ def handle_room_entries(room_entry):

# Now we want to get any newly joined users
newly_joined_users = set()
newly_left_users = set()
if since_token:
for joined_sync in sync_result_builder.joined:
it = itertools.chain(
joined_sync.timeline.events, joined_sync.state.values()
joined_sync.timeline.events, joined_sync.state.itervalues()
)
for event in it:
if event.type == EventTypes.Member:
if event.membership == Membership.JOIN:
newly_joined_users.add(event.state_key)
else:
prev_content = event.unsigned.get("prev_content", {})
prev_membership = prev_content.get("membership", None)
if prev_membership == Membership.JOIN:
newly_left_users.add(event.state_key)

defer.returnValue((newly_joined_rooms, newly_joined_users))
newly_left_users -= newly_joined_users
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this looks dodge. What happens if the user joined and then left? they appear in newly_joined and not newly_left?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh right, we're merging the results across rooms. I think it's ok.

defer.returnValue((newly_joined_rooms, newly_joined_users, [], newly_left_users))

@defer.inlineCallbacks
def _have_rooms_changed(self, sync_result_builder):
Expand Down Expand Up @@ -1259,6 +1298,7 @@ def __init__(self, sync_config, full_state, since_token, now_token):
self.invited = []
self.archived = []
self.device = []
self.to_device = []


class RoomSyncResultBuilder(object):
Expand Down
3 changes: 2 additions & 1 deletion synapse/rest/client/v2_alpha/sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,8 @@ def encode_response(time_now, sync_result, access_token_id, filter):
"account_data": {"events": sync_result.account_data},
"to_device": {"events": sync_result.to_device},
"device_lists": {
"changed": list(sync_result.device_lists),
"changed": list(sync_result.device_lists.changed),
"left": list(sync_result.device_lists.left),
},
"presence": SyncRestServlet.encode_presence(
sync_result.presence, time_now
Expand Down