diff options
author | Erik Johnston <erik@matrix.org> | 2020-01-22 15:39:21 +0000 |
---|---|---|
committer | Erik Johnston <erik@matrix.org> | 2020-01-22 15:39:21 +0000 |
commit | b143e6c68869348d937bc022a7e8f102bfde2dd5 (patch) | |
tree | a06a91c1a03fe696b3e74cda30136969ecd52d69 | |
parent | Refactor HomeServer object to work with type hints (diff) | |
download | synapse-erikj/synapse_server_refactor.tar.xz |
Make it simpler github/erikj/synapse_server_refactor erikj/synapse_server_refactor
-rw-r--r-- | synapse/server.py | 57 |
1 files changed, 23 insertions, 34 deletions
diff --git a/synapse/server.py b/synapse/server.py index 5a0ec4059e..c389739594 100644 --- a/synapse/server.py +++ b/synapse/server.py @@ -113,48 +113,37 @@ FuncType = Callable[..., Any] F = TypeVar("F", bound=FuncType) -class _InjectionDescriptor(object): - """A decorator for HomeServer class to implement dependency injection, i.e. - caching built classes and detecting cyclic dependencies. +def builder(f: F) -> F: + """Decorator to wrap a HomeServer method to cache result and detect + cyclical dependencies. """ + if not f.__name__.startswith("get_"): + raise Exception("Function must be named `get_*`") - def __init__(self, f: F): - self.f = f - - if not f.__name__.startswith("get_"): - raise Exception("Function must be named `get_*`") - - self.depname = self.f.__name__[len("get_") :] # type: str - - def __get__(self, obj, objtype=None): - @wraps(self.f) - def build(): - try: - return getattr(obj, self.depname) - except AttributeError: - pass + depname = f.__name__[len("get_") :] # type: str - # Prevent cyclic dependencies from deadlocking - if self.depname in obj._building: - raise ValueError( - "Cyclic dependency while building %s" % (self.depname,) - ) - obj._building[self.depname] = True + @wraps(f) + def _get(self): + try: + return getattr(self, depname) + except AttributeError: + pass - dep = self.f(obj) + # Prevent cyclic dependencies from deadlocking + if depname in self._building: + raise ValueError("Cyclic dependency while building %s" % (depname,)) - setattr(obj, self.depname, dep) + try: + self._building[depname] = True + dep = f(self) + finally: + self._building.pop(depname, None) - return dep + setattr(self, self.depname, dep) - return build + return dep - -def builder(f: F) -> F: - """Decorator to wrap a HomeServer method to cache result and detect - cyclical dependencies. - """ - return cast(F, _InjectionDescriptor(f)) + return cast(F, _get) class HomeServer(object): |