Skip to content

Commit 0e990e6

Browse files
committed
Explain logging context in run_as_background_process
1 parent 71cd3c4 commit 0e990e6

2 files changed

Lines changed: 27 additions & 0 deletions

File tree

synapse/handlers/delayed_events.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,9 @@ async def cancel(self, requester: Requester, delay_id: str) -> None:
328328
requester,
329329
(requester.user.to_string(), requester.device_id),
330330
)
331+
# TODO: Because the deferred returned by `run_as_background_process` does not
332+
# follow the synapse logcontext rules, this probably messes with log contexts.
333+
# Use `make_deferred_yieldable`
331334
await self._initialized_from_db
332335

333336
next_send_ts = await self._store.cancel_delayed_event(
@@ -354,6 +357,9 @@ async def restart(self, requester: Requester, delay_id: str) -> None:
354357
requester,
355358
(requester.user.to_string(), requester.device_id),
356359
)
360+
# TODO: Because the deferred returned by `run_as_background_process` does not
361+
# follow the synapse logcontext rules, this probably messes with log contexts.
362+
# Use `make_deferred_yieldable`
357363
await self._initialized_from_db
358364

359365
next_send_ts = await self._store.restart_delayed_event(
@@ -380,6 +386,9 @@ async def send(self, requester: Requester, delay_id: str) -> None:
380386
# Use standard request limiter for sending delayed events on-demand,
381387
# as an on-demand send is similar to sending a regular event.
382388
await self._request_ratelimiter.ratelimit(requester)
389+
# TODO: Because the deferred returned by `run_as_background_process` does not
390+
# follow the synapse logcontext rules, this probably messes with log contexts.
391+
# Use `make_deferred_yieldable`
383392
await self._initialized_from_db
384393

385394
event, next_send_ts = await self._store.process_target_delayed_event(

synapse/metrics/background_process_metrics.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,11 @@ def run_as_background_process(
230230
clock.looping_call and friends (or for firing-and-forgetting in the middle of a
231231
normal synapse async function).
232232
233+
Because the returned Deferred does not follow the synapse logcontext rules, awaiting
234+
the result of this function will result in the log context being cleared. In order
235+
to properly await the result of this function and maintain the current log context,
236+
use `make_deferred_yieldable`.
237+
233238
Args:
234239
desc: a description for this background process type
235240
server_name: The homeserver name that this background process is being run for
@@ -285,7 +290,20 @@ async def run() -> Optional[R]:
285290
name=desc, **{SERVER_NAME_LABEL: server_name}
286291
).dec()
287292

293+
# To explain how the log contexts work here:
294+
# - When this function is called, the current context is stored (using
295+
# `PreserveLoggingContext`), we kick off the background task, and we restore the
296+
# original context before returning (also part of `PreserveLoggingContext`).
297+
# - When the background task finishes, we don't want to leak our background context
298+
# into the reactor which would erroneously get attached to the next operation
299+
# picked up by the event loop. We use `PreserveLoggingContext` to set the
300+
# `sentinel` context and means the new `BackgroundProcessLoggingContext` will
301+
# remember the `sentinel` context as its previous context to return to when it
302+
# exits and yields control back to the reactor.
288303
with PreserveLoggingContext():
304+
# The async `run` task is wrapped in a deferred, which will have the side effect
305+
# of executing the coroutine.
306+
#
289307
# Note that we return a Deferred here so that it can be used in a
290308
# looping_call and other places that expect a Deferred.
291309
return defer.ensureDeferred(run())

0 commit comments

Comments
 (0)