diff --git a/synapse/handlers/message.py b/synapse/handlers/message.py
index a74db1dccf..3184bfb047 100644
--- a/synapse/handlers/message.py
+++ b/synapse/handlers/message.py
@@ -1474,23 +1474,23 @@ class EventCreationHandler:
# We now persist the event (and update the cache in parallel, since we
# don't want to block on it).
- event, context = events_and_context[0]
+ #
+ # Note: mypy gets confused if we inline dl and check with twisted#11770.
+ # Some kind of bug in mypy's deduction?
+ deferreds = (
+ run_in_background(
+ self._persist_events,
+ requester=requester,
+ events_and_context=events_and_context,
+ ratelimit=ratelimit,
+ extra_users=extra_users,
+ ),
+ run_in_background(
+ self.cache_joined_hosts_for_events, events_and_context
+ ).addErrback(log_failure, "cache_joined_hosts_for_event failed"),
+ )
result, _ = await make_deferred_yieldable(
- gather_results(
- (
- run_in_background(
- self._persist_events,
- requester=requester,
- events_and_context=events_and_context,
- ratelimit=ratelimit,
- extra_users=extra_users,
- ),
- run_in_background(
- self.cache_joined_hosts_for_events, events_and_context
- ).addErrback(log_failure, "cache_joined_hosts_for_event failed"),
- ),
- consumeErrors=True,
- )
+ gather_results(deferreds, consumeErrors=True)
).addErrback(unwrapFirstError)
return result
diff --git a/synapse/logging/context.py b/synapse/logging/context.py
index f62bea968f..64c6ae4512 100644
--- a/synapse/logging/context.py
+++ b/synapse/logging/context.py
@@ -809,23 +809,24 @@ def run_in_background( # type: ignore[misc]
# `res` may be a coroutine, `Deferred`, some other kind of awaitable, or a plain
# value. Convert it to a `Deferred`.
+ d: "defer.Deferred[R]"
if isinstance(res, typing.Coroutine):
# Wrap the coroutine in a `Deferred`.
- res = defer.ensureDeferred(res)
+ d = defer.ensureDeferred(res)
elif isinstance(res, defer.Deferred):
- pass
+ d = res
elif isinstance(res, Awaitable):
# `res` is probably some kind of completed awaitable, such as a `DoneAwaitable`
# or `Future` from `make_awaitable`.
- res = defer.ensureDeferred(_unwrap_awaitable(res))
+ d = defer.ensureDeferred(_unwrap_awaitable(res))
else:
# `res` is a plain value. Wrap it in a `Deferred`.
- res = defer.succeed(res)
+ d = defer.succeed(res)
- if res.called and not res.paused:
+ if d.called and not d.paused:
# The function should have maintained the logcontext, so we can
# optimise out the messing about
- return res
+ return d
# The function may have reset the context before returning, so
# we need to restore it now.
@@ -843,8 +844,8 @@ def run_in_background( # type: ignore[misc]
# which is supposed to have a single entry and exit point. But
# by spawning off another deferred, we are effectively
# adding a new exit point.)
- res.addBoth(_set_context_cb, ctx)
- return res
+ d.addBoth(_set_context_cb, ctx)
+ return d
T = TypeVar("T")
@@ -877,7 +878,7 @@ def make_deferred_yieldable(deferred: "defer.Deferred[T]") -> "defer.Deferred[T]
ResultT = TypeVar("ResultT")
-def _set_context_cb(result: ResultT, context: LoggingContext) -> ResultT:
+def _set_context_cb(result: ResultT, context: LoggingContextOrSentinel) -> ResultT:
"""A callback function which just sets the logging context"""
set_current_context(context)
return result
diff --git a/synapse/util/caches/deferred_cache.py b/synapse/util/caches/deferred_cache.py
index bf7bd351e0..029eedcc6f 100644
--- a/synapse/util/caches/deferred_cache.py
+++ b/synapse/util/caches/deferred_cache.py
@@ -470,7 +470,7 @@ class CacheMultipleEntries(CacheEntry[KT, VT]):
def deferred(self, key: KT) -> "defer.Deferred[VT]":
if not self._deferred:
self._deferred = ObservableDeferred(defer.Deferred(), consumeErrors=True)
- return self._deferred.observe().addCallback(lambda res: res.get(key))
+ return self._deferred.observe().addCallback(lambda res: res[key])
def add_invalidation_callback(
self, key: KT, callback: Optional[Callable[[], None]]
|