summary refs log tree commit diff
path: root/synapse/events/presence_router.py
diff options
context:
space:
mode:
Diffstat (limited to 'synapse/events/presence_router.py')
-rw-r--r--synapse/events/presence_router.py111
1 files changed, 7 insertions, 104 deletions
diff --git a/synapse/events/presence_router.py b/synapse/events/presence_router.py

index bb4a6bd957..1f1d89fd7e 100644 --- a/synapse/events/presence_router.py +++ b/synapse/events/presence_router.py
@@ -12,93 +12,19 @@ # See the License for the specific language governing permissions and # limitations under the License. import logging -from typing import ( - TYPE_CHECKING, - Any, - Awaitable, - Callable, - Dict, - Iterable, - List, - Optional, - Set, - TypeVar, - Union, -) - -from typing_extensions import ParamSpec +from typing import TYPE_CHECKING, Dict, Iterable, Set, Union from twisted.internet.defer import CancelledError from synapse.api.presence import UserPresenceState -from synapse.util.async_helpers import delay_cancellation, maybe_awaitable +from synapse.util.async_helpers import delay_cancellation if TYPE_CHECKING: from synapse.server import HomeServer -GET_USERS_FOR_STATES_CALLBACK = Callable[ - [Iterable[UserPresenceState]], Awaitable[Dict[str, Set[UserPresenceState]]] -] -# This must either return a set of strings or the constant PresenceRouter.ALL_USERS. -GET_INTERESTED_USERS_CALLBACK = Callable[[str], Awaitable[Union[Set[str], str]]] - logger = logging.getLogger(__name__) -P = ParamSpec("P") -R = TypeVar("R") - - -def load_legacy_presence_router(hs: "HomeServer") -> None: - """Wrapper that loads a presence router module configured using the old - configuration, and registers the hooks they implement. - """ - - if hs.config.server.presence_router_module_class is None: - return - - module = hs.config.server.presence_router_module_class - config = hs.config.server.presence_router_config - api = hs.get_module_api() - - presence_router = module(config=config, module_api=api) - - # The known hooks. If a module implements a method which name appears in this set, - # we'll want to register it. - presence_router_methods = { - "get_users_for_states", - "get_interested_users", - } - - # All methods that the module provides should be async, but this wasn't enforced - # in the old module system, so we wrap them if needed - def async_wrapper( - f: Optional[Callable[P, R]] - ) -> Optional[Callable[P, Awaitable[R]]]: - # f might be None if the callback isn't implemented by the module. In this - # case we don't want to register a callback at all so we return None. - if f is None: - return None - - def run(*args: P.args, **kwargs: P.kwargs) -> Awaitable[R]: - # Assertion required because mypy can't prove we won't change `f` - # back to `None`. See - # https://mypy.readthedocs.io/en/latest/common_issues.html#narrowing-and-inner-functions - assert f is not None - - return maybe_awaitable(f(*args, **kwargs)) - - return run - - # Register the hooks through the module API. - hooks: Dict[str, Optional[Callable[..., Any]]] = { - hook: async_wrapper(getattr(presence_router, hook, None)) - for hook in presence_router_methods - } - - api.register_presence_router_callbacks(**hooks) - - class PresenceRouter: """ A module that the homeserver will call upon to help route user presence updates to @@ -108,30 +34,7 @@ class PresenceRouter: ALL_USERS = "ALL" def __init__(self, hs: "HomeServer"): - # Initially there are no callbacks - self._get_users_for_states_callbacks: List[GET_USERS_FOR_STATES_CALLBACK] = [] - self._get_interested_users_callbacks: List[GET_INTERESTED_USERS_CALLBACK] = [] - - def register_presence_router_callbacks( - self, - get_users_for_states: Optional[GET_USERS_FOR_STATES_CALLBACK] = None, - get_interested_users: Optional[GET_INTERESTED_USERS_CALLBACK] = None, - ) -> None: - # PresenceRouter modules are required to implement both of these methods - # or neither of them as they are assumed to act in a complementary manner - paired_methods = [get_users_for_states, get_interested_users] - if paired_methods.count(None) == 1: - raise RuntimeError( - "PresenceRouter modules must register neither or both of the paired callbacks: " - "[get_users_for_states, get_interested_users]" - ) - - # Append the methods provided to the lists of callbacks - if get_users_for_states is not None: - self._get_users_for_states_callbacks.append(get_users_for_states) - - if get_interested_users is not None: - self._get_interested_users_callbacks.append(get_interested_users) + self._module_api_callbacks = hs.get_module_api_callbacks().presence_router async def get_users_for_states( self, @@ -150,13 +53,13 @@ class PresenceRouter: """ # Bail out early if we don't have any callbacks to run. - if len(self._get_users_for_states_callbacks) == 0: + if len(self._module_api_callbacks.get_users_for_states_callbacks) == 0: # Don't include any extra destinations for presence updates return {} users_for_states: Dict[str, Set[UserPresenceState]] = {} # run all the callbacks for get_users_for_states and combine the results - for callback in self._get_users_for_states_callbacks: + for callback in self._module_api_callbacks.get_users_for_states_callbacks: try: # Note: result is an object here, because we don't trust modules to # return the types they're supposed to. @@ -206,13 +109,13 @@ class PresenceRouter: """ # Bail out early if we don't have any callbacks to run. - if len(self._get_interested_users_callbacks) == 0: + if len(self._module_api_callbacks.get_interested_users_callbacks) == 0: # Don't report any additional interested users return set() interested_users = set() # run all the callbacks for get_interested_users and combine the results - for callback in self._get_interested_users_callbacks: + for callback in self._module_api_callbacks.get_interested_users_callbacks: try: result = await delay_cancellation(callback(user_id)) except CancelledError: