summary refs log tree commit diff
diff options
context:
space:
mode:
-rwxr-xr-xsynapse/app/synctl.py4
-rw-r--r--synapse/handlers/__init__.py2
-rw-r--r--synapse/handlers/events.py2
-rw-r--r--synapse/handlers/message.py4
-rw-r--r--synapse/handlers/presence.py40
-rw-r--r--synapse/handlers/sync.py2
-rw-r--r--synapse/push/pusher.py12
-rw-r--r--synapse/replication/resource.py2
-rw-r--r--synapse/rest/client/v1/presence.py20
-rw-r--r--synapse/rest/client/v1/room.py2
-rw-r--r--synapse/rest/client/v2_alpha/receipts.py2
-rw-r--r--synapse/rest/client/v2_alpha/sync.py2
-rw-r--r--synapse/server.py5
-rw-r--r--tests/replication/test_resource.py2
14 files changed, 64 insertions, 37 deletions
diff --git a/synapse/app/synctl.py b/synapse/app/synctl.py
index ab3a31d7b7..39f4bf6e53 100755
--- a/synapse/app/synctl.py
+++ b/synapse/app/synctl.py
@@ -66,6 +66,10 @@ def main():
 
     config = yaml.load(open(configfile))
     pidfile = config["pid_file"]
+    cache_factor = config.get("synctl_cache_factor", None)
+
+    if cache_factor:
+        os.environ["SYNAPSE_CACHE_FACTOR"] = str(cache_factor)
 
     action = sys.argv[1] if sys.argv[1:] else "usage"
     if action == "start":
diff --git a/synapse/handlers/__init__.py b/synapse/handlers/__init__.py
index f4dbf47c1d..60e31b68ff 100644
--- a/synapse/handlers/__init__.py
+++ b/synapse/handlers/__init__.py
@@ -24,7 +24,6 @@ from .message import MessageHandler
 from .events import EventStreamHandler, EventHandler
 from .federation import FederationHandler
 from .profile import ProfileHandler
-from .presence import PresenceHandler
 from .directory import DirectoryHandler
 from .typing import TypingNotificationHandler
 from .admin import AdminHandler
@@ -53,7 +52,6 @@ class Handlers(object):
         self.event_handler = EventHandler(hs)
         self.federation_handler = FederationHandler(hs)
         self.profile_handler = ProfileHandler(hs)
-        self.presence_handler = PresenceHandler(hs)
         self.room_list_handler = RoomListHandler(hs)
         self.directory_handler = DirectoryHandler(hs)
         self.typing_notification_handler = TypingNotificationHandler(hs)
diff --git a/synapse/handlers/events.py b/synapse/handlers/events.py
index f25a252523..3a3a1257d3 100644
--- a/synapse/handlers/events.py
+++ b/synapse/handlers/events.py
@@ -58,7 +58,7 @@ class EventStreamHandler(BaseHandler):
         If `only_keys` is not None, events from keys will be sent down.
         """
         auth_user = UserID.from_string(auth_user_id)
-        presence_handler = self.hs.get_handlers().presence_handler
+        presence_handler = self.hs.get_presence_handler()
 
         context = yield presence_handler.user_syncing(
             auth_user_id, affect_presence=affect_presence,
diff --git a/synapse/handlers/message.py b/synapse/handlers/message.py
index 9386aeeb1c..c41dafdef5 100644
--- a/synapse/handlers/message.py
+++ b/synapse/handlers/message.py
@@ -236,7 +236,7 @@ class MessageHandler(BaseHandler):
         )
 
         if event.type == EventTypes.Message:
-            presence = self.hs.get_handlers().presence_handler
+            presence = self.hs.get_presence_handler()
             yield presence.bump_presence_active_time(user)
 
     def deduplicate_state_event(self, event, context):
@@ -674,7 +674,7 @@ class MessageHandler(BaseHandler):
             and m.content["membership"] == Membership.JOIN
         ]
 
-        presence_handler = self.hs.get_handlers().presence_handler
+        presence_handler = self.hs.get_presence_handler()
 
         @defer.inlineCallbacks
         def get_presence():
diff --git a/synapse/handlers/presence.py b/synapse/handlers/presence.py
index 72a0b272db..37f57301fb 100644
--- a/synapse/handlers/presence.py
+++ b/synapse/handlers/presence.py
@@ -36,8 +36,6 @@ from synapse.util.wheel_timer import WheelTimer
 from synapse.types import UserID, get_domain_from_id
 import synapse.metrics
 
-from ._base import BaseHandler
-
 import logging
 
 
@@ -73,11 +71,11 @@ FEDERATION_PING_INTERVAL = 25 * 60 * 1000
 assert LAST_ACTIVE_GRANULARITY < IDLE_TIMER
 
 
-class PresenceHandler(BaseHandler):
+class PresenceHandler(object):
 
     def __init__(self, hs):
-        super(PresenceHandler, self).__init__(hs)
-        self.hs = hs
+        self.is_mine = hs.is_mine
+        self.is_mine_id = hs.is_mine_id
         self.clock = hs.get_clock()
         self.store = hs.get_datastore()
         self.wheel_timer = WheelTimer()
@@ -138,7 +136,7 @@ class PresenceHandler(BaseHandler):
                 obj=state.user_id,
                 then=state.last_user_sync_ts + SYNC_ONLINE_TIMEOUT,
             )
-            if self.hs.is_mine_id(state.user_id):
+            if self.is_mine_id(state.user_id):
                 self.wheel_timer.insert(
                     now=now,
                     obj=state.user_id,
@@ -228,7 +226,7 @@ class PresenceHandler(BaseHandler):
 
                 new_state, should_notify, should_ping = handle_update(
                     prev_state, new_state,
-                    is_mine=self.hs.is_mine_id(user_id),
+                    is_mine=self.is_mine_id(user_id),
                     wheel_timer=self.wheel_timer,
                     now=now
                 )
@@ -287,7 +285,7 @@ class PresenceHandler(BaseHandler):
 
             changes = handle_timeouts(
                 states,
-                is_mine_fn=self.hs.is_mine_id,
+                is_mine_fn=self.is_mine_id,
                 user_to_num_current_syncs=self.user_to_num_current_syncs,
                 now=now,
             )
@@ -427,7 +425,7 @@ class PresenceHandler(BaseHandler):
 
         hosts_to_states = {}
         for room_id, states in room_ids_to_states.items():
-            local_states = filter(lambda s: self.hs.is_mine_id(s.user_id), states)
+            local_states = filter(lambda s: self.is_mine_id(s.user_id), states)
             if not local_states:
                 continue
 
@@ -436,7 +434,7 @@ class PresenceHandler(BaseHandler):
                 hosts_to_states.setdefault(host, []).extend(local_states)
 
         for user_id, states in users_to_states.items():
-            local_states = filter(lambda s: self.hs.is_mine_id(s.user_id), states)
+            local_states = filter(lambda s: self.is_mine_id(s.user_id), states)
             if not local_states:
                 continue
 
@@ -611,14 +609,14 @@ class PresenceHandler(BaseHandler):
         # don't need to send to local clients here, as that is done as part
         # of the event stream/sync.
         # TODO: Only send to servers not already in the room.
-        if self.hs.is_mine(user):
+        if self.is_mine(user):
             state = yield self.current_state_for_user(user.to_string())
 
             hosts = yield self.store.get_joined_hosts_for_room(room_id)
             self._push_to_remotes({host: (state,) for host in hosts})
         else:
             user_ids = yield self.store.get_users_in_room(room_id)
-            user_ids = filter(self.hs.is_mine_id, user_ids)
+            user_ids = filter(self.is_mine_id, user_ids)
 
             states = yield self.current_state_for_users(user_ids)
 
@@ -628,7 +626,7 @@ class PresenceHandler(BaseHandler):
     def get_presence_list(self, observer_user, accepted=None):
         """Returns the presence for all users in their presence list.
         """
-        if not self.hs.is_mine(observer_user):
+        if not self.is_mine(observer_user):
             raise SynapseError(400, "User is not hosted on this Home Server")
 
         presence_list = yield self.store.get_presence_list(
@@ -659,7 +657,7 @@ class PresenceHandler(BaseHandler):
             observer_user.localpart, observed_user.to_string()
         )
 
-        if self.hs.is_mine(observed_user):
+        if self.is_mine(observed_user):
             yield self.invite_presence(observed_user, observer_user)
         else:
             yield self.federation.send_edu(
@@ -675,11 +673,11 @@ class PresenceHandler(BaseHandler):
     def invite_presence(self, observed_user, observer_user):
         """Handles new presence invites.
         """
-        if not self.hs.is_mine(observed_user):
+        if not self.is_mine(observed_user):
             raise SynapseError(400, "User is not hosted on this Home Server")
 
         # TODO: Don't auto accept
-        if self.hs.is_mine(observer_user):
+        if self.is_mine(observer_user):
             yield self.accept_presence(observed_user, observer_user)
         else:
             self.federation.send_edu(
@@ -742,7 +740,7 @@ class PresenceHandler(BaseHandler):
         Returns:
             A Deferred.
         """
-        if not self.hs.is_mine(observer_user):
+        if not self.is_mine(observer_user):
             raise SynapseError(400, "User is not hosted on this Home Server")
 
         yield self.store.del_presence_list(
@@ -834,7 +832,11 @@ def _format_user_presence_state(state, now):
 
 class PresenceEventSource(object):
     def __init__(self, hs):
-        self.hs = hs
+        # We can't call get_presence_handler here because there's a cycle:
+        #
+        #   Presence -> Notifier -> PresenceEventSource -> Presence
+        #
+        self.get_presence_handler = hs.get_presence_handler
         self.clock = hs.get_clock()
         self.store = hs.get_datastore()
 
@@ -860,7 +862,7 @@ class PresenceEventSource(object):
                 from_key = int(from_key)
             room_ids = room_ids or []
 
-            presence = self.hs.get_handlers().presence_handler
+            presence = self.get_presence_handler()
             stream_change_cache = self.store.presence_stream_cache
 
             if not room_ids:
diff --git a/synapse/handlers/sync.py b/synapse/handlers/sync.py
index e83f3e9c44..4bdb0aef84 100644
--- a/synapse/handlers/sync.py
+++ b/synapse/handlers/sync.py
@@ -639,7 +639,7 @@ class SyncHandler(BaseHandler):
 
         # For each newly joined room, we want to send down presence of
         # existing users.
-        presence_handler = self.hs.get_handlers().presence_handler
+        presence_handler = self.hs.get_presence_handler()
         extra_presence_users = set()
         for room_id in newly_joined_rooms:
             users = yield self.store.get_users_in_room(event.room_id)
diff --git a/synapse/push/pusher.py b/synapse/push/pusher.py
index e6c0806415..de9c33b936 100644
--- a/synapse/push/pusher.py
+++ b/synapse/push/pusher.py
@@ -18,6 +18,17 @@ from httppusher import HttpPusher
 import logging
 logger = logging.getLogger(__name__)
 
+# We try importing this if we can (it will fail if we don't
+# have the optional email dependencies installed). We don't
+# yet have the config to know if we need the email pusher,
+# but importing this after daemonizing seems to fail
+# (even though a simple test of importing from a daemonized
+# process works fine)
+try:
+    from synapse.push.emailpusher import EmailPusher
+except:
+    pass
+
 
 def create_pusher(hs, pusherdict):
     logger.info("trying to create_pusher for %r", pusherdict)
@@ -28,7 +39,6 @@ def create_pusher(hs, pusherdict):
 
     logger.info("email enable notifs: %r", hs.config.email_enable_notifs)
     if hs.config.email_enable_notifs:
-        from synapse.push.emailpusher import EmailPusher
         PUSHER_TYPES["email"] = EmailPusher
         logger.info("defined email pusher type")
 
diff --git a/synapse/replication/resource.py b/synapse/replication/resource.py
index 0e983ae7fa..b0e7a17670 100644
--- a/synapse/replication/resource.py
+++ b/synapse/replication/resource.py
@@ -109,7 +109,7 @@ class ReplicationResource(Resource):
         self.version_string = hs.version_string
         self.store = hs.get_datastore()
         self.sources = hs.get_event_sources()
-        self.presence_handler = hs.get_handlers().presence_handler
+        self.presence_handler = hs.get_presence_handler()
         self.typing_handler = hs.get_handlers().typing_notification_handler
         self.notifier = hs.notifier
         self.clock = hs.get_clock()
diff --git a/synapse/rest/client/v1/presence.py b/synapse/rest/client/v1/presence.py
index 27d9ed586b..eafdce865e 100644
--- a/synapse/rest/client/v1/presence.py
+++ b/synapse/rest/client/v1/presence.py
@@ -30,20 +30,24 @@ logger = logging.getLogger(__name__)
 class PresenceStatusRestServlet(ClientV1RestServlet):
     PATTERNS = client_path_patterns("/presence/(?P<user_id>[^/]*)/status")
 
+    def __init__(self, hs):
+        super(PresenceStatusRestServlet, self).__init__(hs)
+        self.presence_handler = hs.get_presence_handler()
+
     @defer.inlineCallbacks
     def on_GET(self, request, user_id):
         requester = yield self.auth.get_user_by_req(request)
         user = UserID.from_string(user_id)
 
         if requester.user != user:
-            allowed = yield self.handlers.presence_handler.is_visible(
+            allowed = yield self.presence_handler.is_visible(
                 observed_user=user, observer_user=requester.user,
             )
 
             if not allowed:
                 raise AuthError(403, "You are not allowed to see their presence.")
 
-        state = yield self.handlers.presence_handler.get_state(target_user=user)
+        state = yield self.presence_handler.get_state(target_user=user)
 
         defer.returnValue((200, state))
 
@@ -74,7 +78,7 @@ class PresenceStatusRestServlet(ClientV1RestServlet):
         except:
             raise SynapseError(400, "Unable to parse state")
 
-        yield self.handlers.presence_handler.set_state(user, state)
+        yield self.presence_handler.set_state(user, state)
 
         defer.returnValue((200, {}))
 
@@ -85,6 +89,10 @@ class PresenceStatusRestServlet(ClientV1RestServlet):
 class PresenceListRestServlet(ClientV1RestServlet):
     PATTERNS = client_path_patterns("/presence/list/(?P<user_id>[^/]*)")
 
+    def __init__(self, hs):
+        super(PresenceListRestServlet, self).__init__(hs)
+        self.presence_handler = hs.get_presence_handler()
+
     @defer.inlineCallbacks
     def on_GET(self, request, user_id):
         requester = yield self.auth.get_user_by_req(request)
@@ -96,7 +104,7 @@ class PresenceListRestServlet(ClientV1RestServlet):
         if requester.user != user:
             raise SynapseError(400, "Cannot get another user's presence list")
 
-        presence = yield self.handlers.presence_handler.get_presence_list(
+        presence = yield self.presence_handler.get_presence_list(
             observer_user=user, accepted=True
         )
 
@@ -123,7 +131,7 @@ class PresenceListRestServlet(ClientV1RestServlet):
                 if len(u) == 0:
                     continue
                 invited_user = UserID.from_string(u)
-                yield self.handlers.presence_handler.send_presence_invite(
+                yield self.presence_handler.send_presence_invite(
                     observer_user=user, observed_user=invited_user
                 )
 
@@ -134,7 +142,7 @@ class PresenceListRestServlet(ClientV1RestServlet):
                 if len(u) == 0:
                     continue
                 dropped_user = UserID.from_string(u)
-                yield self.handlers.presence_handler.drop(
+                yield self.presence_handler.drop(
                     observer_user=user, observed_user=dropped_user
                 )
 
diff --git a/synapse/rest/client/v1/room.py b/synapse/rest/client/v1/room.py
index b223fb7e5f..9c89442ce6 100644
--- a/synapse/rest/client/v1/room.py
+++ b/synapse/rest/client/v1/room.py
@@ -570,7 +570,7 @@ class RoomTypingRestServlet(ClientV1RestServlet):
 
     def __init__(self, hs):
         super(RoomTypingRestServlet, self).__init__(hs)
-        self.presence_handler = hs.get_handlers().presence_handler
+        self.presence_handler = hs.get_presence_handler()
 
     @defer.inlineCallbacks
     def on_PUT(self, request, room_id, user_id):
diff --git a/synapse/rest/client/v2_alpha/receipts.py b/synapse/rest/client/v2_alpha/receipts.py
index b831d8c95e..891cef99c6 100644
--- a/synapse/rest/client/v2_alpha/receipts.py
+++ b/synapse/rest/client/v2_alpha/receipts.py
@@ -37,7 +37,7 @@ class ReceiptRestServlet(RestServlet):
         self.hs = hs
         self.auth = hs.get_auth()
         self.receipts_handler = hs.get_handlers().receipts_handler
-        self.presence_handler = hs.get_handlers().presence_handler
+        self.presence_handler = hs.get_presence_handler()
 
     @defer.inlineCallbacks
     def on_POST(self, request, room_id, receipt_type, event_id):
diff --git a/synapse/rest/client/v2_alpha/sync.py b/synapse/rest/client/v2_alpha/sync.py
index 60d3dc4030..812abe22b1 100644
--- a/synapse/rest/client/v2_alpha/sync.py
+++ b/synapse/rest/client/v2_alpha/sync.py
@@ -83,7 +83,7 @@ class SyncRestServlet(RestServlet):
         self.sync_handler = hs.get_handlers().sync_handler
         self.clock = hs.get_clock()
         self.filtering = hs.get_filtering()
-        self.presence_handler = hs.get_handlers().presence_handler
+        self.presence_handler = hs.get_presence_handler()
 
     @defer.inlineCallbacks
     def on_GET(self, request):
diff --git a/synapse/server.py b/synapse/server.py
index ee138de756..6d01b68bd4 100644
--- a/synapse/server.py
+++ b/synapse/server.py
@@ -27,6 +27,7 @@ from synapse.http.client import SimpleHttpClient, InsecureInterceptableContextFa
 from synapse.notifier import Notifier
 from synapse.api.auth import Auth
 from synapse.handlers import Handlers
+from synapse.handlers.presence import PresenceHandler
 from synapse.state import StateHandler
 from synapse.storage import DataStore
 from synapse.util import Clock
@@ -78,6 +79,7 @@ class HomeServer(object):
         'auth',
         'rest_servlet_factory',
         'state_handler',
+        'presence_handler',
         'notifier',
         'distributor',
         'client_resource',
@@ -164,6 +166,9 @@ class HomeServer(object):
     def build_state_handler(self):
         return StateHandler(self)
 
+    def build_presence_handler(self):
+        return PresenceHandler(self)
+
     def build_event_sources(self):
         return EventSources(self)
 
diff --git a/tests/replication/test_resource.py b/tests/replication/test_resource.py
index b1dd7b4a74..1258aaacb1 100644
--- a/tests/replication/test_resource.py
+++ b/tests/replication/test_resource.py
@@ -78,7 +78,7 @@ class ReplicationResourceCase(unittest.TestCase):
     @defer.inlineCallbacks
     def test_presence(self):
         get = self.get(presence="-1")
-        yield self.hs.get_handlers().presence_handler.set_state(
+        yield self.hs.get_presence_handler().set_state(
             self.user, {"presence": "online"}
         )
         code, body = yield get