-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Increase granularity of context. #98
Comments
@alexanderlazarev0 seems promising!
Do you mean that in init method of ContextResource will be created context var and context stack will be stored in it? I approve. And I will provide an example of initial context usage |
@lesnik512 Yes (this was a mistake of mine in the post), since each |
@alexanderlazarev0 this could work, thank you for clarification |
@alexanderlazarev0 I thought about separate context vars. Do we really need this? I think we can achieve described behaviour with single contextvar |
@alexanderlazarev0 about example of initial context usage: this example is quite good https://github.com/modern-python/that-depends/blob/main/tests/integrations/test_fastapi_di_pass_request.py |
Currently, all context resources are managed using one context-variable that stores a dictionary. In practice, this dictionary has a shared namespace (dict-keys) for both:
async with container_context({"my_custom_key" : some_object }): ... ... that can then be retrieved anywhere within that context using: some_object = fetch_context_item("my_custom_key")
Also it is important to note that entering a new container context using: async with container_context() Resets our dict completely without preserving any user set context-resources and provided context-resources. From this I think we have a clear separation of context-resources which I think we should handle differently.
async with container_context(preserve_globals=true): ... Where
Finally, the API would look something like this: @container_context() # resets all context-providers, but global context is preserved
async foo(resource = Provide[MyContainer.context_resource]): ...
@container_context(initial_context=my_custom_context) # set new global context to my_custom_context and reset all providers.
async foo(resource = Provide[MyContainer.context_resource]): ...
@container_context(preserve_globals=false) # completely clean context
async foo(resource = Provide[MyContainer.context_resource]): ...
@container_context(providers=[MyContainer.context_resource]) # reset only the given provider, keep global context.
async foo(resource = Provide[MyContainer.context_resource]): ...
@container_context(containers=[MyContainer]) # reset all context-resources in given container, keep global context.
async foo(resource = Provide[MyContainer.context_resource]): ...
@container_context(providers=[MyContainer.context_resource], preserve_globals=false) # reset given provider and global context.
async foo(resource = Provide[MyContainer.context_resource]): ... And (for completeness):
async def foo():
with container_context(containers=[MyContainer]):
await MyContainer.async_resource.async_resolve() # Error: Cannot resolve async resource in sync container_context() So we should specifically watch out for this case (and also mark it bad practice to enter Please let me know what you think) |
@alexanderlazarev0 I agree that using separate contextvars can be easier to manage, but I have several concerns/questions:
|
My initial approach would be to modify the
Yes
So there is a trade of time-complexity and space-complexity. |
@alexanderlazarev0 ok, let's make separate contextvars then |
Currently,
container_context()
resets/reinitializes the whole context. This makes it hard to manage resources with different lifetimes.As a theoretical workaround, it is possible to build an
initial_context
that keeps resources in the scope, but that requires using context internals (starting with_
).Proposal:
container_context
:container_context
:Implementation details:
ContextResource
manage its own context(var) on a class level.container_context
now just interacts with these context(var)s to set and reset.Goals:
initial_context
@lesnik512 If you approve of this proposal, I will start working on it. I also saw that you make active use of setting the
initial_context
, if you could provide a functional example I will make sure to test against it when converting functionality.The text was updated successfully, but these errors were encountered: