forked from MirrorHub/synapse
First hack at implementing timeouts in typing notification handler
This commit is contained in:
parent
4551afc6d2
commit
9eb819e828
2 changed files with 52 additions and 6 deletions
|
@ -43,7 +43,8 @@ class TypingNotificationHandler(BaseHandler):
|
||||||
|
|
||||||
self.federation.register_edu_handler("m.typing", self._recv_edu)
|
self.federation.register_edu_handler("m.typing", self._recv_edu)
|
||||||
|
|
||||||
self._member_typing_until = {}
|
self._member_typing_until = {} # clock time we expect to stop
|
||||||
|
self._member_typing_timer = {} # deferreds to manage theabove
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def started_typing(self, target_user, auth_user, room_id, timeout):
|
def started_typing(self, target_user, auth_user, room_id, timeout):
|
||||||
|
@ -58,7 +59,13 @@ class TypingNotificationHandler(BaseHandler):
|
||||||
|
|
||||||
was_present = member in self._member_typing_until
|
was_present = member in self._member_typing_until
|
||||||
|
|
||||||
|
if member in self._member_typing_timer:
|
||||||
|
self.clock.cancel_call_later(self._member_typing_timer[member])
|
||||||
|
|
||||||
self._member_typing_until[member] = until
|
self._member_typing_until[member] = until
|
||||||
|
self._member_typing_timer[member] = self.clock.call_later(
|
||||||
|
timeout / 1000, lambda: self._stopped_typing(member)
|
||||||
|
)
|
||||||
|
|
||||||
if was_present:
|
if was_present:
|
||||||
# No point sending another notification
|
# No point sending another notification
|
||||||
|
@ -80,16 +87,25 @@ class TypingNotificationHandler(BaseHandler):
|
||||||
|
|
||||||
member = RoomMember(room_id=room_id, user=target_user)
|
member = RoomMember(room_id=room_id, user=target_user)
|
||||||
|
|
||||||
|
yield self._stopped_typing(member)
|
||||||
|
|
||||||
|
@defer.inlineCallbacks
|
||||||
|
def _stopped_typing(self, member):
|
||||||
if member not in self._member_typing_until:
|
if member not in self._member_typing_until:
|
||||||
# No point
|
# No point
|
||||||
defer.returnValue(None)
|
defer.returnValue(None)
|
||||||
|
|
||||||
yield self._push_update(
|
yield self._push_update(
|
||||||
room_id=room_id,
|
room_id=member.room_id,
|
||||||
user=target_user,
|
user=member.user,
|
||||||
typing=False,
|
typing=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
del self._member_typing_until[member]
|
||||||
|
|
||||||
|
self.clock.cancel_call_later(self._member_typing_timer[member])
|
||||||
|
del self._member_typing_timer[member]
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def _push_update(self, room_id, user, typing):
|
def _push_update(self, room_id, user, typing):
|
||||||
localusers = set()
|
localusers = set()
|
||||||
|
|
|
@ -238,9 +238,11 @@ class TypingNotificationsTestCase(unittest.TestCase):
|
||||||
|
|
||||||
# Gut-wrenching
|
# Gut-wrenching
|
||||||
from synapse.handlers.typing import RoomMember
|
from synapse.handlers.typing import RoomMember
|
||||||
self.handler._member_typing_until[
|
member = RoomMember(self.room_id, self.u_apple)
|
||||||
RoomMember(self.room_id, self.u_apple)
|
self.handler._member_typing_until[member] = 1002000
|
||||||
] = 1002000
|
self.handler._member_typing_timer[member] = (
|
||||||
|
self.clock.call_later(1002, lambda: 0)
|
||||||
|
)
|
||||||
|
|
||||||
yield self.handler.stopped_typing(
|
yield self.handler.stopped_typing(
|
||||||
target_user=self.u_apple,
|
target_user=self.u_apple,
|
||||||
|
@ -256,3 +258,31 @@ class TypingNotificationsTestCase(unittest.TestCase):
|
||||||
])
|
])
|
||||||
|
|
||||||
yield put_json.await_calls()
|
yield put_json.await_calls()
|
||||||
|
|
||||||
|
@defer.inlineCallbacks
|
||||||
|
def test_typing_timeout(self):
|
||||||
|
self.room_members = [self.u_apple, self.u_banana]
|
||||||
|
|
||||||
|
yield self.handler.started_typing(
|
||||||
|
target_user=self.u_apple,
|
||||||
|
auth_user=self.u_apple,
|
||||||
|
room_id=self.room_id,
|
||||||
|
timeout=10000,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.mock_update_client.assert_has_calls([
|
||||||
|
call(observer_user=self.u_banana,
|
||||||
|
observed_user=self.u_apple,
|
||||||
|
room_id=self.room_id,
|
||||||
|
typing=True),
|
||||||
|
])
|
||||||
|
self.mock_update_client.reset_mock()
|
||||||
|
|
||||||
|
self.clock.advance_time(11)
|
||||||
|
|
||||||
|
self.mock_update_client.assert_has_calls([
|
||||||
|
call(observer_user=self.u_banana,
|
||||||
|
observed_user=self.u_apple,
|
||||||
|
room_id=self.room_id,
|
||||||
|
typing=False),
|
||||||
|
])
|
||||||
|
|
Loading…
Reference in a new issue