diff options
author | Richard van der Hoff <richard@matrix.org> | 2015-11-10 18:27:23 +0000 |
---|---|---|
committer | Richard van der Hoff <richard@matrix.org> | 2015-11-13 10:39:09 +0000 |
commit | fddedd51d9ca44f385d412e8c2e3e8d99325ba67 (patch) | |
tree | 76ca546f99c26540cc8a50122a149ab64c0c0228 /synapse/storage/state.py | |
parent | Make handlers.sync return a state dictionary, instead of an event list. (diff) | |
download | synapse-fddedd51d9ca44f385d412e8c2e3e8d99325ba67.tar.xz |
Fix a few race conditions in the state calculation
Be a bit more careful about how we calculate the state to be returned by /sync. In a few places, it was possible for /sync to return slightly later state than that represented by the next_batch token and the timeline. In particular, the following cases were susceptible: * On a full state sync, for an active room * During a per-room incremental sync with a timeline gap * When the user has just joined a room. (Refactor check_joined_room to make it less magical) Also, use store.get_state_for_events() (and thus the existing stategroups) to calculate the state corresponding to a particular sync position, rather than state_handler.compute_event_context(), which recalculates from first principles (and tends to miss some state). Merged from PR https://github.com/matrix-org/synapse/pull/372
Diffstat (limited to 'synapse/storage/state.py')
-rw-r--r-- | synapse/storage/state.py | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/synapse/storage/state.py b/synapse/storage/state.py index acfb322a53..80e9b63f50 100644 --- a/synapse/storage/state.py +++ b/synapse/storage/state.py @@ -237,6 +237,20 @@ class StateStore(SQLBaseStore): defer.returnValue({event: event_to_state[event] for event in event_ids}) + @defer.inlineCallbacks + def get_state_for_event(self, event_id, types=None): + """ + Get the state dict corresponding to a particular event + + :param str event_id: event whose state should be returned + :param list[(str, str)]|None types: List of (type, state_key) tuples + which are used to filter the state fetched. May be None, which + matches any key + :return: a deferred dict from (type, state_key) -> state_event + """ + state_map = yield self.get_state_for_events([event_id], types) + defer.returnValue(state_map[event_id]) + @cached(num_args=2, lru=True, max_entries=10000) def _get_state_group_for_event(self, room_id, event_id): return self._simple_select_one_onecol( |