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