From 6c6aba76e1059f103ed48487e74ab4161347638b Mon Sep 17 00:00:00 2001 From: Neil Johnson Date: Fri, 10 Aug 2018 15:12:59 +0100 Subject: implementation of server notices to alert on hitting resource limits --- .../resource_limits_server_notices.py | 77 +++++++++++++--------- synapse/server_notices/server_notices_sender.py | 33 ++++++---- 2 files changed, 65 insertions(+), 45 deletions(-) (limited to 'synapse') diff --git a/synapse/server_notices/resource_limits_server_notices.py b/synapse/server_notices/resource_limits_server_notices.py index 33b1d80cd9..017828f81e 100644 --- a/synapse/server_notices/resource_limits_server_notices.py +++ b/synapse/server_notices/resource_limits_server_notices.py @@ -14,14 +14,9 @@ # limitations under the License. import logging -from six import iteritems, string_types - from twisted.internet import defer -from synapse.api.errors import SynapseError -from synapse.api.urls import ConsentURIBuilder -from synapse.config import ConfigError -from synapse.types import get_localpart_from_id +from synapse.api.errors import AuthError, SynapseError logger = logging.getLogger(__name__) @@ -37,12 +32,12 @@ class ResourceLimitsServerNotices(object): """ self._server_notices_manager = hs.get_server_notices_manager() self._store = hs.get_datastore() - self._api = hs.get_api() + self.auth = hs.get_auth() self._server_notice_content = hs.config.user_consent_server_notice_content - self._limit_usage_by_mau = config.limit_usage_by_mau = False - self._hs_disabled.config.hs_disabled = False + self._limit_usage_by_mau = hs.config.limit_usage_by_mau = False + self._hs_disabled = hs.config.hs_disabled - self._notified = set() + self._notified_of_blocking = set() self._resouce_limited = False # Config checks? @@ -56,29 +51,49 @@ class ResourceLimitsServerNotices(object): Returns: Deferred """ - if self._limit_usage_by_mau is False and self._hs_disabled is False: - # not enabled + if self._hs_disabled is True: return - timestamp = yield self.store.user_last_seen_monthly_active(user_id) - if timestamp is None: - # This user will be blocked from receiving the notice anyway - return - try: - yield self.api.check_auth_blocking() - if self._resouce_limited: + if self._limit_usage_by_mau is True: + timestamp = yield self._store.user_last_seen_monthly_active(user_id) + if timestamp is None: + # This user will be blocked from receiving the notice anyway. + # In practice, not sure we can ever get here + return + try: + yield self.auth.check_auth_blocking() + self._resouce_limited = False # Need to start removing notices - pass - except AuthError as e: - # Need to start notifying of blocking - if not self._resouce_limited: - pass + if user_id in self._notified_of_blocking: + # Send message to remove warning - needs updating + content = "remove warning" + self._send_server_notice(user_id, content) + self._notified_of_blocking.remove(user_id) - # need to send a message. - try: - yield self._server_notices_manager.send_notice( - user_id, content, - ) + except AuthError: + # Need to start notifying of blocking + + self._resouce_limited = True + if user_id not in self._notified_of_blocking: + # Send message to add warning - needs updating + content = "add warning" + self._send_server_notice(user_id, content) + self._notified_of_blocking.add(user_id) - except SynapseError as e: - logger.error("Error sending server notice about resource limits: %s", e) + @defer.inlineCallbacks + def _send_server_notice(self, user_id, content): + """Sends Server notice + + Args: + user_id(str): The user to send to + content(str): The content of the message + + Returns: + Deferred[] + """ + try: + yield self._server_notices_manager.send_notice( + user_id, content, + ) + except SynapseError as e: + logger.error("Error sending server notice about resource limits: %s", e) diff --git a/synapse/server_notices/server_notices_sender.py b/synapse/server_notices/server_notices_sender.py index 5d23965f34..6121b2f267 100644 --- a/synapse/server_notices/server_notices_sender.py +++ b/synapse/server_notices/server_notices_sender.py @@ -12,7 +12,12 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +from twisted.internet import defer + from synapse.server_notices.consent_server_notices import ConsentServerNotices +from synapse.server_notices.resource_limits_server_notices import ( + ResourceLimitsServerNotices, +) class ServerNoticesSender(object): @@ -25,34 +30,34 @@ class ServerNoticesSender(object): Args: hs (synapse.server.HomeServer): """ - # todo: it would be nice to make this more dynamic - self._consent_server_notices = ConsentServerNotices(hs) + self._server_notices = ( + ConsentServerNotices(hs), + ResourceLimitsServerNotices(hs) + ) + @defer.inlineCallbacks def on_user_syncing(self, user_id): """Called when the user performs a sync operation. Args: user_id (str): mxid of user who synced - - Returns: - Deferred """ - return self._consent_server_notices.maybe_send_server_notice_to_user( - user_id, - ) + for sn in self._server_notices: + yield sn.maybe_send_server_notice_to_user( + user_id, + ) + @defer.inlineCallbacks def on_user_ip(self, user_id): """Called on the master when a worker process saw a client request. Args: user_id (str): mxid - - Returns: - Deferred """ # The synchrotrons use a stubbed version of ServerNoticesSender, so # we check for notices to send to the user in on_user_ip as well as # in on_user_syncing - return self._consent_server_notices.maybe_send_server_notice_to_user( - user_id, - ) + for sn in self._server_notices: + yield sn.maybe_send_server_notice_to_user( + user_id, + ) -- cgit 1.4.1