aiohttp客户端在^C过早关闭会话

2024-05-07 07:38:49 发布

您现在位置:Python中文网/ 问答频道 /正文

我在Ubuntu 16.04上使用aiohttp V2.0.7和python3.5.2时遇到了如下代码中嵌套块的问题:

while True:
    try:
        async with aiohttp.ClientSession() as session:
            with contextlib.closing(MyServerSession(loop, session)) as ss:
                # this was simplified for testing!
                done, pending = await asyncio.wait(job1(ss), job2(ss))
    except aiohttp.ClientError as ce:
        log.error("HTTP session lost, retrying", client_error=ce)
        time.sleep(10)

MyServerSession()实现close()在服务器上注销,但点击^C会产生:

^{pr2}$

看起来aiohttp在注销完成之前关闭了会话?!在

我不知道如何进一步调试它? 我错过了什么?在


Tags: 代码trueasyncaiohttpsessionubuntuaswith
1条回答
网友
1楼 · 发布于 2024-05-07 07:38:49

现在回答我自己的问题。在

在下面的测试中显示了asnyc上下文管理器,首先使用块嵌套了2个async,然后使用contextlib中的closing()进行了一个嵌套。在

class asy_context1:
    def __aenter__(self):
        print("c1: enter")
        return asyncio.sleep(0.3)
    def __aexit__(self, exc_type, exc, tb):
        print("c1: exit")
        return asyncio.sleep(0.3)

class asy_context2:
    def __aenter__(self):
        print("c2: enter")
        return asyncio.sleep(0.1)
    def __aexit__(self, exc_type, exc, tb):
        print("c2: exit")
        return asyncio.sleep(0.1)

async def test2async_withs():
    async with asy_context1() as a1:
        async with asy_context2() as a2:
            pass
            # raise RuntimeError("unexpected")  # also works

from contextlib import closing

class asy_context3:
    def __init__(self, loop):
        self.loop = loop
    async def logout(self):
        print("logging out")
    def close(self):
        print("c3:close")
        self.loop.run_until_complete(self.logout())

async def test_mixed_withs(loop):
    async with asy_context1() as a1:
        with closing(asy_context3(loop)) as a3:
            pass
            # raise RuntimeError("unexpected")

loop = asyncio.get_event_loop()
loop.run_until_complete(test2async_withs())
loop.run_until_complete(test_mixed_withs(loop))
loop.close()

其输出为:

^{pr2}$

当嵌套的异步上下文管理器按预期工作时,closing()的用法却不能。在

重点似乎是,asy\u context3.close()中新循环开始的时间没有定义。close()是按顺序调用的,但是循环运行直到完成close()中的()似乎被安排在asy\u context1.\uuxit\uuu()之后。在

在contextlib.关闭()显然不打算在异步上下文中使用。在

相关问题 更多 >