Factor run_in_background out from preserve_fn

It annoys me that we create temporary function objects when there's really no
need for it. Let's factor the gubbins out of preserve_fn and start using it.
pull/2961/head
Richard van der Hoff 2018-03-07 19:59:24 +00:00
parent 8ffaacbee3
commit 20f40348d4
2 changed files with 32 additions and 27 deletions

View File

@ -279,9 +279,9 @@ Obviously that option means that the operations done in
that might be fixed by setting a different logcontext via a ``with
LoggingContext(...)`` in ``background_operation``).
The second option is to use ``logcontext.preserve_fn``, which wraps a function
so that it doesn't reset the logcontext even when it returns an incomplete
deferred, and adds a callback to the returned deferred to reset the
The second option is to use ``logcontext.run_in_background``, which wraps a
function so that it doesn't reset the logcontext even when it returns an
incomplete deferred, and adds a callback to the returned deferred to reset the
logcontext. In other words, it turns a function that follows the Synapse rules
about logcontexts and Deferreds into one which behaves more like an external
function — the opposite operation to that described in the previous section.
@ -293,7 +293,7 @@ It can be used like this:
def do_request_handling():
yield foreground_operation()
logcontext.preserve_fn(background_operation)()
logcontext.run_in_background(background_operation)
# this will now be logged against the request context
logger.debug("Request handling complete")

View File

@ -292,14 +292,20 @@ class PreserveLoggingContext(object):
def preserve_fn(f):
"""Wraps a function, to ensure that the current context is restored after
"""Function decorator which wraps the function with run_in_background"""
def g(*args, **kwargs):
return run_in_background(f, *args, **kwargs)
return g
def run_in_background(f, *args, **kwargs):
"""Calls a function, ensuring that the current context is restored after
return from the function, and that the sentinel context is set once the
deferred returned by the funtion completes.
Useful for wrapping functions that return a deferred which you don't yield
on.
"""
def g(*args, **kwargs):
current = LoggingContext.current_context()
res = f(*args, **kwargs)
if isinstance(res, defer.Deferred) and not res.called:
@ -321,7 +327,6 @@ def preserve_fn(f):
# adding a new exit point.)
res.addBoth(_set_context_cb, LoggingContext.sentinel)
return res
return g
def make_deferred_yieldable(deferred):