Process closings in any case

This commit is contained in:
Artem Ivanov 2023-11-28 13:19:17 +01:00
parent cc2304e46e
commit d001b2930e
No known key found for this signature in database
GPG Key ID: 9CDBF79098EC04A0
2 changed files with 1766 additions and 942 deletions

File diff suppressed because it is too large Load Diff

View File

@ -25,17 +25,17 @@ def _get_sync_patched(fn, patched: PatchedCallable):
if arg_key not in kwargs or isinstance(kwargs[arg_key], _Marker): if arg_key not in kwargs or isinstance(kwargs[arg_key], _Marker):
to_inject[arg_key] = provider() to_inject[arg_key] = provider()
result = fn(*args, **to_inject) try:
return fn(*args, **to_inject)
finally:
if patched.closing:
for arg_key, provider in patched.closing.items():
if arg_key in kwargs and not isinstance(kwargs[arg_key], _Marker):
continue
if not isinstance(provider, providers.Resource):
continue
provider.shutdown()
if patched.closing:
for arg_key, provider in patched.closing.items():
if arg_key in kwargs and not isinstance(kwargs[arg_key], _Marker):
continue
if not isinstance(provider, providers.Resource):
continue
provider.shutdown()
return result
return _patched return _patched
@ -53,7 +53,7 @@ async def _async_inject(object fn, tuple args, dict kwargs, dict injections, dic
provide = provider() provide = provider()
if provider.is_async_mode_enabled(): if provider.is_async_mode_enabled():
to_inject_await.append((arg_key, provide)) to_inject_await.append((arg_key, provide))
elif _isawaitable(provide): elif _is_awaitable(provide):
to_inject_await.append((arg_key, provide)) to_inject_await.append((arg_key, provide))
else: else:
to_inject[arg_key] = provide to_inject[arg_key] = provide
@ -62,25 +62,24 @@ async def _async_inject(object fn, tuple args, dict kwargs, dict injections, dic
async_to_inject = await asyncio.gather(*(provide for _, provide in to_inject_await)) async_to_inject = await asyncio.gather(*(provide for _, provide in to_inject_await))
for provide, (injection, _) in zip(async_to_inject, to_inject_await): for provide, (injection, _) in zip(async_to_inject, to_inject_await):
to_inject[injection] = provide to_inject[injection] = provide
try:
return await fn(*args, **to_inject)
finally:
if closings:
for arg_key, provider in closings.items():
if arg_key in kwargs and isinstance(kwargs[arg_key], _Marker):
continue
if not isinstance(provider, providers.Resource):
continue
shutdown = provider.shutdown()
if _is_awaitable(shutdown):
to_close_await.append(shutdown)
result = await fn(*args, **to_inject) await asyncio.gather(*to_close_await)
if closings:
for arg_key, provider in closings.items():
if arg_key in kwargs and isinstance(kwargs[arg_key], _Marker):
continue
if not isinstance(provider, providers.Resource):
continue
shutdown = provider.shutdown()
if _isawaitable(shutdown):
to_close_await.append(shutdown)
await asyncio.gather(*to_close_await)
return result
cdef bint _isawaitable(object instance):
cdef bint _is_awaitable(object instance):
"""Return true if object can be passed to an ``await`` expression.""" """Return true if object can be passed to an ``await`` expression."""
return (isinstance(instance, types.CoroutineType) or return (isinstance(instance, types.CoroutineType) or
isinstance(instance, types.GeneratorType) and isinstance(instance, types.GeneratorType) and