Add Measures to presence

This commit is contained in:
Erik Johnston 2016-02-19 11:50:48 +00:00
parent 4a95eb0a12
commit 24d9f2c140

View File

@ -31,6 +31,7 @@ from synapse.storage.presence import UserPresenceState
from synapse.util.logcontext import preserve_fn from synapse.util.logcontext import preserve_fn
from synapse.util.logutils import log_function from synapse.util.logutils import log_function
from synapse.util.metrics import Measure
from synapse.util.wheel_timer import WheelTimer from synapse.util.wheel_timer import WheelTimer
from synapse.types import UserID from synapse.types import UserID
import synapse.metrics import synapse.metrics
@ -209,57 +210,60 @@ class PresenceHandler(BaseHandler):
""" """
now = self.clock.time_msec() now = self.clock.time_msec()
# NOTE: We purposefully don't yield between now and when we've with Measure(self.clock, "presence_update_states"):
# calculated what we want to do with the new states, to avoid races.
to_notify = {} # Changes we want to notify everyone about # NOTE: We purposefully don't yield between now and when we've
to_federation_ping = {} # These need sending keep-alives # calculated what we want to do with the new states, to avoid races.
for new_state in new_states:
user_id = new_state.user_id
# Its fine to not hit the database here, as the only thing not in to_notify = {} # Changes we want to notify everyone about
# the current state cache are OFFLINE states, where the only field to_federation_ping = {} # These need sending keep-alives
# of interest is last_active which is safe enough to assume is 0
# here.
prev_state = self.user_to_current_state.get(
user_id, UserPresenceState.default(user_id)
)
new_state, should_notify, should_ping = handle_update( for new_state in new_states:
prev_state, new_state, user_id = new_state.user_id
is_mine=self.hs.is_mine_id(user_id),
wheel_timer=self.wheel_timer,
now=now
)
self.user_to_current_state[user_id] = new_state # Its fine to not hit the database here, as the only thing not in
# the current state cache are OFFLINE states, where the only field
# of interest is last_active which is safe enough to assume is 0
# here.
prev_state = self.user_to_current_state.get(
user_id, UserPresenceState.default(user_id)
)
if should_notify: new_state, should_notify, should_ping = handle_update(
to_notify[user_id] = new_state prev_state, new_state,
elif should_ping: is_mine=self.hs.is_mine_id(user_id),
to_federation_ping[user_id] = new_state wheel_timer=self.wheel_timer,
now=now
)
# TODO: We should probably ensure there are no races hereafter self.user_to_current_state[user_id] = new_state
presence_updates_counter.inc_by(len(new_states)) if should_notify:
to_notify[user_id] = new_state
elif should_ping:
to_federation_ping[user_id] = new_state
if to_notify: # TODO: We should probably ensure there are no races hereafter
notified_presence_counter.inc_by(len(to_notify))
yield self._persist_and_notify(to_notify.values())
self.unpersisted_users_changes |= set(s.user_id for s in new_states) presence_updates_counter.inc_by(len(new_states))
self.unpersisted_users_changes -= set(to_notify.keys())
to_federation_ping = { if to_notify:
user_id: state for user_id, state in to_federation_ping.items() notified_presence_counter.inc_by(len(to_notify))
if user_id not in to_notify yield self._persist_and_notify(to_notify.values())
}
if to_federation_ping:
_, _, hosts_to_states = yield self._get_interested_parties(
to_federation_ping.values()
)
self._push_to_remotes(hosts_to_states) self.unpersisted_users_changes |= set(s.user_id for s in new_states)
self.unpersisted_users_changes -= set(to_notify.keys())
to_federation_ping = {
user_id: state for user_id, state in to_federation_ping.items()
if user_id not in to_notify
}
if to_federation_ping:
_, _, hosts_to_states = yield self._get_interested_parties(
to_federation_ping.values()
)
self._push_to_remotes(hosts_to_states)
def _handle_timeouts(self): def _handle_timeouts(self):
"""Checks the presence of users that have timed out and updates as """Checks the presence of users that have timed out and updates as
@ -267,26 +271,27 @@ class PresenceHandler(BaseHandler):
""" """
now = self.clock.time_msec() now = self.clock.time_msec()
# Fetch the list of users that *may* have timed out. Things may have with Measure(self.clock, "presence_handle_timeouts"):
# changed since the timeout was set, so we won't necessarily have to # Fetch the list of users that *may* have timed out. Things may have
# take any action. # changed since the timeout was set, so we won't necessarily have to
users_to_check = self.wheel_timer.fetch(now) # take any action.
users_to_check = self.wheel_timer.fetch(now)
states = [ states = [
self.user_to_current_state.get( self.user_to_current_state.get(
user_id, UserPresenceState.default(user_id) user_id, UserPresenceState.default(user_id)
)
for user_id in set(users_to_check)
]
timers_fired_counter.inc_by(len(states))
changes = handle_timeouts(
states,
is_mine_fn=self.hs.is_mine_id,
user_to_num_current_syncs=self.user_to_num_current_syncs,
now=now,
) )
for user_id in set(users_to_check)
]
timers_fired_counter.inc_by(len(states))
changes = handle_timeouts(
states,
is_mine_fn=self.hs.is_mine_id,
user_to_num_current_syncs=self.user_to_num_current_syncs,
now=now,
)
preserve_fn(self._update_states)(changes) preserve_fn(self._update_states)(changes)