Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/342.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python aiohttp客户端在^C上过早关闭会话_Python_Aiohttp - Fatal编程技术网

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

Python aiohttp客户端在^C上过早关闭会话,python,aiohttp,Python,Aiohttp,我在Ubuntu 16.04上使用aiohttp V2.0.7和Python 3.5.2,在代码中嵌套块时遇到如下问题: while True: try: async with aiohttp.ClientSession() as session: with contextlib.closing(MyServerSession(loop, session)) as ss: # this was simplified

我在Ubuntu 16.04上使用aiohttp V2.0.7和Python 3.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会产生:

future: <Task finished coro=<MyServerSession.logout() done, defined at my_server.py:134> exception=RuntimeError('Session is closed',)>
Traceback (most recent call last):
  File "/usr/lib/python3.5/asyncio/tasks.py", line 239, in _step
    result = coro.send(None)
  File "my_server.py", line 75, in _do_REST
    async with self.session.request(verb, self.url + '/' + resource, timeout=timeout, **kwargs) as resp:
  File "/usr/local/lib/python3.5/dist-packages/aiohttp/client.py", line 626, in __aenter__
    self._resp = yield from self._coro
  File "/usr/local/lib/python3.5/dist-packages/aiohttp/client.py", line 164, in _request
    raise RuntimeError('Session is closed')
RuntimeError: Session is closed
未来:
回溯(最近一次呼叫最后一次):
文件“/usr/lib/python3.5/asyncio/tasks.py”,第239行,步骤
结果=coro.send(无)
文件“my_server.py”,第75行,在_do_REST中
与self.session.request(动词,self.url+'/'+resource,timeout=timeout,**kwargs)异步,分别为:
文件“/usr/local/lib/python3.5/dist-packages/aiohttp/client.py”,第626行,在__
self.\u resp=self.\u coro的收益
文件“/usr/local/lib/python3.5/dist-packages/aiohttp/client.py”,第164行,在请求中
raise RUNTIMERROR('会话已关闭')
运行时错误:会话已关闭
看起来aiohttp在注销完成之前关闭了会话

我不知道如何进一步调试它?
我遗漏了什么?现在回答我自己的问题

在以下测试中,将显示asnyc上下文管理器,前两个嵌套异步块,然后一个使用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()
其输出为:

c1: enter
c2: enter
c2: exit
c1: exit
c1: enter
c3:close
c1: exit
logging out
Traceback (most recent call last):
  File "test_exceptions.py", line 143, in <module>
    test_case2()
  File "test_exceptions.py", line 140, in test_case2
    loop.run_until_complete(test_mixed_withs(loop))
  File "/usr/lib/python3.5/asyncio/base_events.py", line 385, in run_until_complete
    raise RuntimeError('Event loop stopped before Future completed.')
RuntimeError: Event loop stopped before Future completed.
c1:输入
c2:进入
c2:出口
c1:出口
c1:输入
c3:关闭
c1:出口
注销
回溯(最近一次呼叫最后一次):
文件“test_exceptions.py”,第143行,在
测试案例2()
文件“test_exceptions.py”,第140行,在test_案例2中
循环。运行直到完成(测试与(循环)混合)
文件“/usr/lib/python3.5/asyncio/base\u events.py”,第385行,运行直到完成
raise RUNTIMERROR('事件循环在未来完成之前已停止')
RuntimeError:事件循环在未来完成之前停止。
虽然嵌套的异步上下文管理器可以按预期工作,但closing()的用法却不能

问题似乎是,在asy_context3.close()中新循环开始的时间没有定义。close()是按顺序调用的,但close()中的循环.run_until_complete()似乎安排在asy_context1.\uuuuuuuuxit_uuu()之后


contextlib.closing()显然不是要在异步IO上下文中使用。

我忘了,MyServerSession有
def close(self):如果不是self.need\u登录:self.loop。运行\u直到完成(self.logout())