我想要一个异步上下文管理器,以确保托管进程在通过正常终止或强制终止(无论是否取消)退出之前已完成。例如,
async def sleep(duration):
proc = await asyncio.create_subprocess_exec('sleep', str(duration))
async with manage_process(proc):
...
# proc either finished, was terminated, or killed.
到目前为止,我最好的是:
@asynccontextmanager
async def manage_process(
proc: asyncio.subprocess.Process,
timeout: Optional[float] = None,
) -> AsyncIterator[asyncio.subprocess.Process]:
if timeout is None:
timeout = 1.0
try:
yield proc
finally:
try:
proc.terminate()
except ProcessLookupError:
pass
else:
try:
await asyncio.shield(asyncio.wait_for(proc.wait(), timeout))
except asyncio.CancelledError:
is_done = False
is_cancelled = True
except asyncio.TimeoutError:
is_done = False
is_cancelled = False
else:
is_done = True
is_cancelled = False
if not is_done:
try:
proc.kill()
except ProcessLookupError:
pass
else:
await asyncio.shield(proc.wait())
if is_cancelled:
raise asyncio.CancelledError()
我不确定我是否正确处理了取消。我使用过asyncio.shield()
,但不确定我是否正确执行。