我试图测试我的python 3.4.3 http客户端或将HTTP请求发送到服务器的应用程序。如果服务器由于某种原因而有延迟响应,我希望请求不应该阻塞,因为asyncio + aiohttp应该提供异步调用:
def post(self):
print("received post")
print(self.request)
print("POST Body: %s" % str(self.request.body))
time.sleep(3)
self.write("blah")
self.finish()
我只是想知道为什么我的代码/ http客户端阻塞了:
import aiohttp, asyncio, async_timeout
@asyncio.coroutine
def fetch(session, url):
with aiohttp.Timeout(30):
try:
response = yield from session.get(url)
print((yield from response.read()))
return response
except Exception as e:
raise e
finally:
try:
response.release()
except:
pass
@asyncio.coroutine
def post(session, url):
with aiohttp.Timeout(30):
try:
response = yield from session.post(url)
print((yield from response.read()))
return response
except Exception as e:
raise e
finally:
try:
response.release()
except:
pass
@asyncio.coroutine
def close_connection(session):
try:
session.close()
except:
pass
if __name__ == '__main__':
loop = asyncio.get_event_loop()
session = aiohttp.ClientSession(loop=loop)
try:
for i in range(10):
html = loop.run_until_complete(post(session, 'http://localhost:8000'))
except Exception as e:
print("received exception %s." % type(e).__name__)
# Close session if not closed.
loop.run_until_complete(close_connection(session))
我尝试做一个循环,我遍历10个URL(这里是相同的一个)。如果它是顺序的,我希望它需要约30秒(服务器响应3秒延迟)。对于异步,我的期望是它需要更少。
try:
for i in range(10):
html = loop.run_until_complete(post(session, 'http://localhost:8000'))
是" run_until_complete()"阻塞的功能?如何使其无阻塞?
答案 0 :(得分:3)
基本上,当你使用run_until_complete()
时,你告诉事件循环运行作为参数传递的协同程序并在完成时返回结果。简而言之,run_until_complete()
将阻塞,直到完成该操作。
基于您的for循环代码段。基本上在每个循环中,run_until_complete
将阻塞,在此上下文中运行协程(post
),返回结果,然后只有下一个循环才会继续执行。
您要在此处执行的操作是同时运行所有post
。你可以做的是使用asyncio.gather()
。
try:
html = loop.run_until_complete(asyncio.gather(*[post(session, 'http://localhost:8000') for i in range(10)]))