This repository has been archived by the owner on Apr 26, 2024. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Split out edu/query registration to a separate class #2976
Merged
Merged
Changes from 2 commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,7 +17,7 @@ | |
import simplejson as json | ||
from twisted.internet import defer | ||
|
||
from synapse.api.errors import AuthError, FederationError, SynapseError | ||
from synapse.api.errors import AuthError, FederationError, SynapseError, NotFoundError | ||
from synapse.crypto.event_signing import compute_event_signature | ||
from synapse.federation.federation_base import ( | ||
FederationBase, | ||
|
@@ -56,6 +56,8 @@ def __init__(self, hs): | |
self._server_linearizer = async.Linearizer("fed_server") | ||
self._transaction_linearizer = async.Linearizer("fed_txn_handler") | ||
|
||
self.registry = hs.get_federation_registry() | ||
|
||
# We cache responses to state queries, as they take a while and often | ||
# come in waves. | ||
self._state_resp_cache = ResponseCache(hs, timeout_ms=30000) | ||
|
@@ -67,35 +69,6 @@ def set_handler(self, handler): | |
""" | ||
self.handler = handler | ||
|
||
def register_edu_handler(self, edu_type, handler): | ||
if edu_type in self.edu_handlers: | ||
raise KeyError("Already have an EDU handler for %s" % (edu_type,)) | ||
|
||
self.edu_handlers[edu_type] = handler | ||
|
||
def register_query_handler(self, query_type, handler): | ||
"""Sets the handler callable that will be used to handle an incoming | ||
federation Query of the given type. | ||
|
||
Args: | ||
query_type (str): Category name of the query, which should match | ||
the string used by make_query. | ||
handler (callable): Invoked to handle incoming queries of this type | ||
|
||
handler is invoked as: | ||
result = handler(args) | ||
|
||
where 'args' is a dict mapping strings to strings of the query | ||
arguments. It should return a Deferred that will eventually yield an | ||
object to encode as JSON. | ||
""" | ||
if query_type in self.query_handlers: | ||
raise KeyError( | ||
"Already have a Query handler for %s" % (query_type,) | ||
) | ||
|
||
self.query_handlers[query_type] = handler | ||
|
||
@defer.inlineCallbacks | ||
@log_function | ||
def on_backfill_request(self, origin, room_id, versions, limit): | ||
|
@@ -229,16 +202,7 @@ def process_pdus_for_room(room_id): | |
@defer.inlineCallbacks | ||
def received_edu(self, origin, edu_type, content): | ||
received_edus_counter.inc() | ||
|
||
if edu_type in self.edu_handlers: | ||
try: | ||
yield self.edu_handlers[edu_type](origin, content) | ||
except SynapseError as e: | ||
logger.info("Failed to handle edu %r: %r", edu_type, e) | ||
except Exception as e: | ||
logger.exception("Failed to handle edu %r", edu_type) | ||
else: | ||
logger.warn("Received EDU of type %s with no handler", edu_type) | ||
yield self.registry.on_edu(edu_type, origin, content) | ||
|
||
@defer.inlineCallbacks | ||
@log_function | ||
|
@@ -328,14 +292,8 @@ def on_pull_request(self, origin, versions): | |
@defer.inlineCallbacks | ||
def on_query_request(self, query_type, args): | ||
received_queries_counter.inc(query_type) | ||
|
||
if query_type in self.query_handlers: | ||
response = yield self.query_handlers[query_type](args) | ||
defer.returnValue((200, response)) | ||
else: | ||
defer.returnValue( | ||
(404, "No handler for Query type '%s'" % (query_type,)) | ||
) | ||
resp = yield self.registry.on_query(query_type, args) | ||
defer.returnValue((200, resp)) | ||
|
||
@defer.inlineCallbacks | ||
def on_make_join_request(self, room_id, user_id): | ||
|
@@ -607,3 +565,66 @@ def on_exchange_third_party_invite_request(self, origin, room_id, event_dict): | |
origin, room_id, event_dict | ||
) | ||
defer.returnValue(ret) | ||
|
||
|
||
class FederationHandlerRegistry(object): | ||
"""Allows classes to register themselves as handlers for a given EDU or | ||
query type for incoming federation traffic. | ||
""" | ||
def __init__(self): | ||
self.edu_handlers = {} | ||
self.query_handlers = {} | ||
|
||
def register_edu_handler(self, edu_type, handler): | ||
"""Sets the handler callable that will be used to handle an incoming | ||
federation EDU of the given type. | ||
|
||
Args: | ||
edu_type (str): The type of the incoming EDU to register handler for | ||
handler (Callable[str, dict]): A callable invoked on incoming EDU | ||
of the given type. The arguments are the origin server name and | ||
the EDU contents. | ||
""" | ||
if edu_type in self.edu_handlers: | ||
raise KeyError("Already have an EDU handler for %s" % (edu_type,)) | ||
|
||
self.edu_handlers[edu_type] = handler | ||
|
||
def register_query_handler(self, query_type, handler): | ||
"""Sets the handler callable that will be used to handle an incoming | ||
federation query of the given type. | ||
|
||
Args: | ||
query_type (str): Category name of the query, which should match | ||
the string used by make_query. | ||
handler (Callable[dict] -> Deferred[dict]): Invoked to handle | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
incoming queries of this type. The return will be yielded | ||
on and the result used as the response to the query request. | ||
""" | ||
if query_type in self.query_handlers: | ||
raise KeyError( | ||
"Already have a Query handler for %s" % (query_type,) | ||
) | ||
|
||
self.query_handlers[query_type] = handler | ||
|
||
@defer.inlineCallbacks | ||
def on_edu(self, edu_type, origin, content): | ||
handler = self.edu_handlers.get(edu_type) | ||
if not handler: | ||
logger.warn("No handler registered for EDU type %s", edu_type) | ||
|
||
try: | ||
yield handler(origin, content) | ||
except SynapseError as e: | ||
logger.info("Failed to handle edu %r: %r", edu_type, e) | ||
except Exception as e: | ||
logger.exception("Failed to handle edu %r", edu_type) | ||
|
||
def on_query(self, query_type, args): | ||
handler = self.query_handlers.get(query_type) | ||
if not handler: | ||
logger.warn("No handler registered for query type %s", query_type) | ||
raise NotFoundError("No handler for Query type '%s'" % (query_type,)) | ||
|
||
return handler(args) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think
Callable[str, dict]
means "a thing that takes a str and returns a dict". You probably wantCallable[[str, dict], Deferred[None]]
or something?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, I misread the thingy. Ta.