Only send presence "poll"/"unpoll" EDUs when changing from/to zero remotes
This commit is contained in:
parent
113342a756
commit
efc5f3440d
|
@ -437,16 +437,22 @@ class PresenceHandler(BaseHandler):
|
||||||
)
|
)
|
||||||
|
|
||||||
def _start_polling_remote(self, user, domain, remoteusers):
|
def _start_polling_remote(self, user, domain, remoteusers):
|
||||||
|
to_poll = set()
|
||||||
|
|
||||||
for u in remoteusers:
|
for u in remoteusers:
|
||||||
if u not in self._remote_recvmap:
|
if u not in self._remote_recvmap:
|
||||||
self._remote_recvmap[u] = set()
|
self._remote_recvmap[u] = set()
|
||||||
|
to_poll.add(u)
|
||||||
|
|
||||||
self._remote_recvmap[u].add(user)
|
self._remote_recvmap[u].add(user)
|
||||||
|
|
||||||
|
if not to_poll:
|
||||||
|
return defer.succeed(None)
|
||||||
|
|
||||||
return self.federation.send_edu(
|
return self.federation.send_edu(
|
||||||
destination=domain,
|
destination=domain,
|
||||||
edu_type="m.presence",
|
edu_type="m.presence",
|
||||||
content={"poll": [u.to_string() for u in remoteusers]}
|
content={"poll": [u.to_string() for u in to_poll]}
|
||||||
)
|
)
|
||||||
|
|
||||||
def stop_polling_presence(self, user, target_user=None):
|
def stop_polling_presence(self, user, target_user=None):
|
||||||
|
@ -489,16 +495,22 @@ class PresenceHandler(BaseHandler):
|
||||||
del self._local_pushmap[localpart]
|
del self._local_pushmap[localpart]
|
||||||
|
|
||||||
def _stop_polling_remote(self, user, domain, remoteusers):
|
def _stop_polling_remote(self, user, domain, remoteusers):
|
||||||
|
to_unpoll = set()
|
||||||
|
|
||||||
for u in remoteusers:
|
for u in remoteusers:
|
||||||
self._remote_recvmap[u].remove(user)
|
self._remote_recvmap[u].remove(user)
|
||||||
|
|
||||||
if not self._remote_recvmap[u]:
|
if not self._remote_recvmap[u]:
|
||||||
del self._remote_recvmap[u]
|
del self._remote_recvmap[u]
|
||||||
|
to_unpoll.add(u)
|
||||||
|
|
||||||
|
if not to_unpoll:
|
||||||
|
return defer.succeed(None)
|
||||||
|
|
||||||
return self.federation.send_edu(
|
return self.federation.send_edu(
|
||||||
destination=domain,
|
destination=domain,
|
||||||
edu_type="m.presence",
|
edu_type="m.presence",
|
||||||
content={"unpoll": [u.to_string() for u in remoteusers]}
|
content={"unpoll": [u.to_string() for u in to_unpoll]}
|
||||||
)
|
)
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
|
|
||||||
from twisted.trial import unittest
|
from twisted.trial import unittest
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer, reactor
|
||||||
|
|
||||||
from mock import Mock, call, ANY
|
from mock import Mock, call, ANY
|
||||||
import logging
|
import logging
|
||||||
|
@ -853,6 +853,7 @@ class PresencePollingTestCase(unittest.TestCase):
|
||||||
'apple': [ "@banana:test", "@clementine:test" ],
|
'apple': [ "@banana:test", "@clementine:test" ],
|
||||||
'banana': [ "@apple:test" ],
|
'banana': [ "@apple:test" ],
|
||||||
'clementine': [ "@apple:test", "@potato:remote" ],
|
'clementine': [ "@apple:test", "@potato:remote" ],
|
||||||
|
'fig': [ "@potato:remote" ],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -902,9 +903,10 @@ class PresencePollingTestCase(unittest.TestCase):
|
||||||
# Mocked database state
|
# Mocked database state
|
||||||
# Local users always start offline
|
# Local users always start offline
|
||||||
self.current_user_state = {
|
self.current_user_state = {
|
||||||
"apple": OFFLINE,
|
"apple": OFFLINE,
|
||||||
"banana": OFFLINE,
|
"banana": OFFLINE,
|
||||||
"clementine": OFFLINE,
|
"clementine": OFFLINE,
|
||||||
|
"fig": OFFLINE,
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_presence_state(user_localpart):
|
def get_presence_state(user_localpart):
|
||||||
|
@ -934,6 +936,7 @@ class PresencePollingTestCase(unittest.TestCase):
|
||||||
self.u_apple = hs.parse_userid("@apple:test")
|
self.u_apple = hs.parse_userid("@apple:test")
|
||||||
self.u_banana = hs.parse_userid("@banana:test")
|
self.u_banana = hs.parse_userid("@banana:test")
|
||||||
self.u_clementine = hs.parse_userid("@clementine:test")
|
self.u_clementine = hs.parse_userid("@clementine:test")
|
||||||
|
self.u_fig = hs.parse_userid("@fig:test")
|
||||||
|
|
||||||
# Remote users
|
# Remote users
|
||||||
self.u_potato = hs.parse_userid("@potato:remote")
|
self.u_potato = hs.parse_userid("@potato:remote")
|
||||||
|
@ -1023,10 +1026,32 @@ class PresencePollingTestCase(unittest.TestCase):
|
||||||
yield put_json.await_calls()
|
yield put_json.await_calls()
|
||||||
|
|
||||||
# Gut-wrenching tests
|
# Gut-wrenching tests
|
||||||
self.assertTrue(self.u_potato in self.handler._remote_recvmap)
|
self.assertTrue(self.u_potato in self.handler._remote_recvmap,
|
||||||
|
msg="expected potato to be in _remote_recvmap"
|
||||||
|
)
|
||||||
self.assertTrue(self.u_clementine in
|
self.assertTrue(self.u_clementine in
|
||||||
self.handler._remote_recvmap[self.u_potato])
|
self.handler._remote_recvmap[self.u_potato])
|
||||||
|
|
||||||
|
# fig goes online; shouldn't send a second poll
|
||||||
|
yield self.handler.set_state(
|
||||||
|
target_user=self.u_fig, auth_user=self.u_fig,
|
||||||
|
state={"state": ONLINE}
|
||||||
|
)
|
||||||
|
|
||||||
|
reactor.iterate(delay=0)
|
||||||
|
|
||||||
|
put_json.assert_had_no_calls()
|
||||||
|
|
||||||
|
# fig goes offline
|
||||||
|
yield self.handler.set_state(
|
||||||
|
target_user=self.u_fig, auth_user=self.u_fig,
|
||||||
|
state={"state": OFFLINE}
|
||||||
|
)
|
||||||
|
|
||||||
|
reactor.iterate(delay=0)
|
||||||
|
|
||||||
|
put_json.assert_had_no_calls()
|
||||||
|
|
||||||
put_json.expect_call_and_return(
|
put_json.expect_call_and_return(
|
||||||
call("remote",
|
call("remote",
|
||||||
path="/matrix/federation/v1/send/1000001/",
|
path="/matrix/federation/v1/send/1000001/",
|
||||||
|
@ -1046,7 +1071,9 @@ class PresencePollingTestCase(unittest.TestCase):
|
||||||
|
|
||||||
put_json.await_calls()
|
put_json.await_calls()
|
||||||
|
|
||||||
self.assertFalse(self.u_potato in self.handler._remote_recvmap)
|
self.assertFalse(self.u_potato in self.handler._remote_recvmap,
|
||||||
|
msg="expected potato not to be in _remote_recvmap"
|
||||||
|
)
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def test_remote_poll_receive(self):
|
def test_remote_poll_receive(self):
|
||||||
|
|
Loading…
Reference in New Issue