at a django project, i have a lot of code that depends on thread_locals: middlewares using correlation ids, other logic depending on these middlewares, cached info about the request and so on.
recently i started to mix sync code with async, and since i have a single thread serving the async part, i cannot use thread_locals anymore. since i'm using lots of sync_to_async
and async_to_sync
adapters, i cannot use context vars, because at the same request different coroutines are executed the context is copied accordingly, making contextvars the right replacement for thread_locals
what alternatives do i have to manage short lived information that is unique to each request? i thought about to store everything on a redis as cache, but again, how show i generate/retrieve the key from each request on several points through its execution?
CodePudding user response:
Python has the contextvars
lib module to provide some of the functionality of thread-locals to async code. https://docs.python.org/3/library/contextvars.html -
however, the API for contextvars is not the same - to the contrary, each context_var can only bear a single value, and have to be set and reset by method-calling instead of the =
operator.
I've created a project before contextvars was official which attempts to provide a "context" which works more closely like threadlocals - -if you want to try it, it currently has to be pip-installed directly from git - the major problem being I had no real-world project needing it which took me to go the extra-mile needed to polish it for publication on Pypi -
Nonetheless, it works flawlessly with all test scenarios I could come up with - the project is at https://github.com/jsbueno/extracontext and can be pip installed with pip install git https://github.com/jsbueno/[email protected]