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:
|