I've noticed that the BaseContainer.tear_down method tears down resources in alphabetical order (due to the implementation of inspect.getmembers). This can sometimes cause errors if one resource depends on another.
For instance:
async def resource(name, **kwargs):
print("init resource", name, "depends on", kwargs)
yield name
print(name, "closed")
class Container(BaseContainer):
a = providers.AsyncResource(resource, "A")
b = providers.AsyncResource(resource, "B", a=a) # B depends on A
async def main():
await Container.init_async_resources()
print("...")
await Container.tear_down()
if __name__ == "__main__":
asyncio.run(main())
This code will print:
init resource A depends on {}
init resource B depends on {'a': 'A'}
...
A closed
B closed
Resource A closes before resource B, despite the fact that B depends on A. If there is code during the teardown of resource B that expects resource A to still be in a valid state (i.e., open), errors are highly likely to occur.
Wouldn't it be more appropriate to tear down resources in the order of dependency? In this case, B should be torn down first, followed by A.
Hello!
I've noticed that the
BaseContainer.tear_down
method tears down resources in alphabetical order (due to the implementation ofinspect.getmembers
). This can sometimes cause errors if one resource depends on another.For instance:
This code will print:
Resource
A
closes before resourceB
, despite the fact thatB
depends onA
. If there is code during the teardown of resourceB
that expects resource A to still be in a valid state (i.e., open), errors are highly likely to occur.Wouldn't it be more appropriate to tear down resources in the order of dependency? In this case,
B
should be torn down first, followed byA
.