Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Add a remote user profile cache #2429

Merged
merged 4 commits into from
Aug 25, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions synapse/groups/groups_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,13 @@ def invite_to_group(self, group_id, user_id, requester_user_id, content):
get_domain_from_id(user_id), group_id, user_id, content
)

user_profile = res.get("user_profile", {})
yield self.store.add_remote_profile_cache(
user_id,
displayname=user_profile.get("displayname"),
avatar_url=user_profile.get("avatar_url"),
)

if res["state"] == "join":
if not self.hs.is_mine_id(user_id):
remote_attestation = res["attestation"]
Expand Down Expand Up @@ -627,6 +634,9 @@ def remove_user_from_group(self, group_id, user_id, requester_user_id, content):
get_domain_from_id(user_id), group_id, user_id, {}
)

if not self.hs.is_mine_id(user_id):
yield self.store.maybe_delete_remote_profile_cache(user_id)

defer.returnValue({})

@defer.inlineCallbacks
Expand All @@ -647,6 +657,7 @@ def create_group(self, group_id, user_id, content):
avatar_url = profile.get("avatar_url")
short_description = profile.get("short_description")
long_description = profile.get("long_description")
user_profile = content.get("user_profile", {})

yield self.store.create_group(
group_id,
Expand Down Expand Up @@ -679,6 +690,13 @@ def create_group(self, group_id, user_id, content):
remote_attestation=remote_attestation,
)

if not self.hs.is_mine_id(user_id):
yield self.store.add_remote_profile_cache(
user_id,
displayname=user_profile.get("displayname"),
avatar_url=user_profile.get("avatar_url"),
)

defer.returnValue({
"group_id": group_id,
})
Expand Down
2 changes: 0 additions & 2 deletions synapse/handlers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
from .room_member import RoomMemberHandler
from .message import MessageHandler
from .federation import FederationHandler
from .profile import ProfileHandler
from .directory import DirectoryHandler
from .admin import AdminHandler
from .identity import IdentityHandler
Expand Down Expand Up @@ -52,7 +51,6 @@ def __init__(self, hs):
self.room_creation_handler = RoomCreationHandler(hs)
self.room_member_handler = RoomMemberHandler(hs)
self.federation_handler = FederationHandler(hs)
self.profile_handler = ProfileHandler(hs)
self.directory_handler = DirectoryHandler(hs)
self.admin_handler = AdminHandler(hs)
self.identity_handler = IdentityHandler(hs)
Expand Down
16 changes: 12 additions & 4 deletions synapse/handlers/groups_local.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ def __init__(self, hs):
self.notifier = hs.get_notifier()
self.attestations = hs.get_groups_attestation_signing()

self.profile_handler = hs.get_profile_handler()

# Ensure attestations get renewed
hs.get_groups_attestation_renewer()

Expand Down Expand Up @@ -123,20 +125,24 @@ def get_group_summary(self, group_id, requester_user_id):

defer.returnValue(res)

@defer.inlineCallbacks
def create_group(self, group_id, user_id, content):
"""Create a group
"""

logger.info("Asking to create group with ID: %r", group_id)

if self.is_mine_id(group_id):
return self.groups_server_handler.create_group(
res = yield self.groups_server_handler.create_group(
group_id, user_id, content
)
defer.returnValue(res)

return self.transport_client.create_group(
content["user_profile"] = yield self.profile_handler.get_profile(user_id)
res = yield self.transport_client.create_group(
get_domain_from_id(group_id), group_id, user_id, content,
) # TODO
)
defer.returnValue(res)

@defer.inlineCallbacks
def get_users_in_group(self, group_id, requester_user_id):
Expand Down Expand Up @@ -265,7 +271,9 @@ def on_invite(self, group_id, user_id, content):
"groups_key", token, users=[user_id],
)

defer.returnValue({"state": "invite"})
user_profile = yield self.profile_handler.get_profile(user_id)

defer.returnValue({"state": "invite", "user_profile": user_profile})

@defer.inlineCallbacks
def remove_user_from_group(self, group_id, user_id, requester_user_id, content):
Expand Down
3 changes: 2 additions & 1 deletion synapse/handlers/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ def __init__(self, hs):
self.state = hs.get_state_handler()
self.clock = hs.get_clock()
self.validator = EventValidator()
self.profile_handler = hs.get_profile_handler()

self.pagination_lock = ReadWriteLock()

Expand Down Expand Up @@ -210,7 +211,7 @@ def create_event(self, requester, event_dict, token_id=None, txn_id=None,

if membership in {Membership.JOIN, Membership.INVITE}:
# If event doesn't include a display name, add one.
profile = self.hs.get_handlers().profile_handler
profile = self.profile_handler
content = builder.content

try:
Expand Down
80 changes: 78 additions & 2 deletions synapse/handlers/profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,15 @@

import synapse.types
from synapse.api.errors import SynapseError, AuthError, CodeMessageException
from synapse.types import UserID
from synapse.types import UserID, get_domain_from_id
from ._base import BaseHandler


logger = logging.getLogger(__name__)


class ProfileHandler(BaseHandler):
PROFILE_UPDATE_MS = 60 * 1000
PROFILE_UPDATE_EVERY_MS = 24 * 60 * 60 * 1000

def __init__(self, hs):
super(ProfileHandler, self).__init__(hs)
Expand All @@ -36,6 +37,40 @@ def __init__(self, hs):
"profile", self.on_profile_query
)

self.clock.looping_call(self._update_remote_profile_cache, self.PROFILE_UPDATE_MS)

@defer.inlineCallbacks
def get_profile(self, user_id):
target_user = UserID.from_string(user_id)
if self.hs.is_mine(target_user):
displayname = yield self.store.get_profile_displayname(
target_user.localpart
)
avatar_url = yield self.store.get_profile_avatar_url(
target_user.localpart
)

defer.returnValue({
"displayname": displayname,
"avatar_url": avatar_url,
})
else:
try:
result = yield self.federation.make_query(
destination=target_user.domain,
query_type="profile",
args={
"user_id": user_id,
},
ignore_backoff=True,
)
defer.returnValue(result)
except CodeMessageException as e:
if e.code != 404:
logger.exception("Failed to get displayname")

raise

@defer.inlineCallbacks
def get_displayname(self, target_user):
if self.hs.is_mine(target_user):
Expand Down Expand Up @@ -182,3 +217,44 @@ def _update_join_states(self, requester):
"Failed to update join event for room %s - %s",
room_id, str(e.message)
)

def _update_remote_profile_cache(self):
"""Called periodically to check profiles of remote users we haven't
checked in a while.
"""
entries = yield self.store.get_remote_profile_cache_entries_that_expire(
last_checked=self.clock.time_msec() - self.PROFILE_UPDATE_EVERY_MS
)

for user_id, displayname, avatar_url in entries:
is_subscribed = yield self.store.is_subscribed_remote_profile_for_user(
user_id,
)
if not is_subscribed:
yield self.store.maybe_delete_remote_profile_cache(user_id)
continue

try:
profile = yield self.federation.make_query(
destination=get_domain_from_id(user_id),
query_type="profile",
args={
"user_id": user_id,
},
ignore_backoff=True,
)
except:
logger.exception("Failed to get avatar_url")

yield self.store.update_remote_profile_cache(
user_id, displayname, avatar_url
)
continue

new_name = profile.get("displayname")
new_avatar = profile.get("avatar_url")

# We always hit update to update the last_check timestamp
yield self.store.update_remote_profile_cache(
user_id, new_name, new_avatar
)
4 changes: 2 additions & 2 deletions synapse/handlers/register.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ def __init__(self, hs):
super(RegistrationHandler, self).__init__(hs)

self.auth = hs.get_auth()
self.profile_handler = hs.get_profile_handler()
self.captcha_client = CaptchaServerHttpClient(hs)

self._next_generated_user_id = None
Expand Down Expand Up @@ -423,8 +424,7 @@ def get_or_create_user(self, requester, localpart, displayname,

if displayname is not None:
logger.info("setting user display name: %s -> %s", user_id, displayname)
profile_handler = self.hs.get_handlers().profile_handler
yield profile_handler.set_displayname(
yield self.profile_handler.set_displayname(
user, requester, displayname, by_admin=True,
)

Expand Down
4 changes: 3 additions & 1 deletion synapse/handlers/room_member.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ class RoomMemberHandler(BaseHandler):
def __init__(self, hs):
super(RoomMemberHandler, self).__init__(hs)

self.profile_handler = hs.get_profile_handler()

self.member_linearizer = Linearizer(name="member")

self.clock = hs.get_clock()
Expand Down Expand Up @@ -255,7 +257,7 @@ def _update_membership(

content["membership"] = Membership.JOIN

profile = self.hs.get_handlers().profile_handler
profile = self.profile_handler
if not content_specified:
content["displayname"] = yield profile.get_displayname(target)
content["avatar_url"] = yield profile.get_avatar_url(target)
Expand Down
18 changes: 9 additions & 9 deletions synapse/rest/client/v1/profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ class ProfileDisplaynameRestServlet(ClientV1RestServlet):

def __init__(self, hs):
super(ProfileDisplaynameRestServlet, self).__init__(hs)
self.handlers = hs.get_handlers()
self.profile_handler = hs.get_profile_handler()

@defer.inlineCallbacks
def on_GET(self, request, user_id):
user = UserID.from_string(user_id)

displayname = yield self.handlers.profile_handler.get_displayname(
displayname = yield self.profile_handler.get_displayname(
user,
)

Expand All @@ -55,7 +55,7 @@ def on_PUT(self, request, user_id):
except:
defer.returnValue((400, "Unable to parse name"))

yield self.handlers.profile_handler.set_displayname(
yield self.profile_handler.set_displayname(
user, requester, new_name, is_admin)

defer.returnValue((200, {}))
Expand All @@ -69,13 +69,13 @@ class ProfileAvatarURLRestServlet(ClientV1RestServlet):

def __init__(self, hs):
super(ProfileAvatarURLRestServlet, self).__init__(hs)
self.handlers = hs.get_handlers()
self.profile_handler = hs.get_profile_handler()

@defer.inlineCallbacks
def on_GET(self, request, user_id):
user = UserID.from_string(user_id)

avatar_url = yield self.handlers.profile_handler.get_avatar_url(
avatar_url = yield self.profile_handler.get_avatar_url(
user,
)

Expand All @@ -97,7 +97,7 @@ def on_PUT(self, request, user_id):
except:
defer.returnValue((400, "Unable to parse name"))

yield self.handlers.profile_handler.set_avatar_url(
yield self.profile_handler.set_avatar_url(
user, requester, new_name, is_admin)

defer.returnValue((200, {}))
Expand All @@ -111,16 +111,16 @@ class ProfileRestServlet(ClientV1RestServlet):

def __init__(self, hs):
super(ProfileRestServlet, self).__init__(hs)
self.handlers = hs.get_handlers()
self.profile_handler = hs.get_profile_handler()

@defer.inlineCallbacks
def on_GET(self, request, user_id):
user = UserID.from_string(user_id)

displayname = yield self.handlers.profile_handler.get_displayname(
displayname = yield self.profile_handler.get_displayname(
user,
)
avatar_url = yield self.handlers.profile_handler.get_avatar_url(
avatar_url = yield self.profile_handler.get_avatar_url(
user,
)

Expand Down
5 changes: 5 additions & 0 deletions synapse/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
from synapse.handlers.read_marker import ReadMarkerHandler
from synapse.handlers.user_directory import UserDirectoyHandler
from synapse.handlers.groups_local import GroupsLocalHandler
from synapse.handlers.profile import ProfileHandler
from synapse.groups.groups_server import GroupsServerHandler
from synapse.groups.attestations import GroupAttestionRenewer, GroupAttestationSigning
from synapse.http.client import SimpleHttpClient, InsecureInterceptableContextFactory
Expand Down Expand Up @@ -114,6 +115,7 @@ def build_DEPENDENCY(self)
'application_service_scheduler',
'application_service_handler',
'device_message_handler',
'profile_handler',
'notifier',
'distributor',
'client_resource',
Expand Down Expand Up @@ -258,6 +260,9 @@ def build_event_stream_handler(self):
def build_initial_sync_handler(self):
return InitialSyncHandler(self)

def build_profile_handler(self):
return ProfileHandler(self)

def build_event_sources(self):
return EventSources(self)

Expand Down
Loading