If I have a structure in an async webserver like
import contextvars
...
my_context_var = contextvars.ContextVar("var")
@app.route("/foo") # decorator from webserver
async def some_web_endpoint():
local_ctx_var = my_context_var.set(params.get("bar")) # app sets params
await some_function_that_can_raise()
local_ctx_var.reset()
Will it leak memory if I don't wrap the ContextVar
in a finally:
block and some_function_that_can_raise()
raises an Exception?
(without such a case, .reset()
would never be called)
try:
await some_function_that_can_raise()
finally:
local_ctx_var.reset()
.. or is it safe to assume the value will be destroyed when the request scope ends?
The async example in the upstream docs doesn't actually bother .reset()
-ing it at all!
In such a case, .reset()
is redundant as it happens right before the context is cleaned up anyways.
To add some more context (ha), I'm recently learning about ContextVars and I assume the second is the case.
local_ctx_var
is the only name which refers to the Token (from .set()
), and as the name is deleted when the request scope ends, the local value should become candidate for garbage collection, preventing a potential leak and making .reset()
unnecessary for short-lived scopes (hooray)
..but I'm not absolutely certain, and while there's some very extremely helpful information on the subject, it muddles the mixture slightly
- What happens if I don't reset Python's ContextVars? (implies it'll be GC'd as one would expect)
- Context variables in Python (explicitly uses
finally:
)