我试图利用Python的新asyncio库来发送异步HTTP请求。我想在发送每个请求之前等待几毫秒(timeout
变量) - 但当然 - 异步发送它们,而不是在每个请求发送后等待响应。
我正在执行以下操作:
@asyncio.coroutine
def handle_line(self, line, destination):
print("Inside! line {} destination {}".format(line, destination))
response = yield from aiohttp.request('POST', destination, data=line,
headers=tester.headers)
print(response.status)
return (yield from response.read())
@asyncio.coroutine
def send_data(self, filename, timeout):
destination='foo'
logging.log(logging.DEBUG, 'sending_data')
with open(filename) as log_file:
for line in log_file:
try:
json_event = json.loads(line)
except ValueError as e:
print("Error parsing json event")
time.sleep(timeout)
yield from asyncio.async(self.handle_line(json.dumps(json_event), destination))
loop=asyncio.get_event_loop().run_until_complete(send_data('foo.txt', 1))
我得到的输出(通过打印200个响应)看起来这个代码是同步运行的。我做错了什么?
答案 0 :(得分:6)
这里有几个问题:
您应该使用asyncio.sleep
,而不是time.sleep
,因为后者会阻止事件循环。
yield from
调用后你不应该使用asyncio.async(self.handle_line(...))
,因为这会使脚本阻塞,直到self.handle_line
协程完成,这意味着你不能#39; t最终同时做任何事情;你处理每一行,等待处理完成,然后转到下一行。相反,您应该在不等待的情况下运行所有asyncio.async
个调用,保存返回到列表的Task
个对象,然后使用asyncio.wait
等待它们全部完成开始他们所有。
把所有这些放在一起:
@asyncio.coroutine
def handle_line(self, line, destination):
print("Inside! line {} destination {}".format(line, destination))
response = yield from aiohttp.request('POST', destination, data=line,
headers=tester.headers)
print(response.status)
return (yield from response.read())
@asyncio.coroutine
def send_data(self, filename, timeout):
destination='foo'
logging.log(logging.DEBUG, 'sending_data')
tasks = []
with open(filename) as log_file:
for line in log_file:
try:
json_event = json.loads(line)
except ValueError as e:
print("Error parsing json event")
yield from asyncio.sleep(timeout)
tasks.append(asyncio.async(
self.handle_line(json.dumps(json_event), destination))
yield from asyncio.wait(tasks)
asyncio.get_event_loop().run_until_complete(send_data('foo.txt', 1))