我使用aioredis编写异步服务,该服务将侦听某个频道并以异步方式运行某些命令。
基本上我从examples page获取代码来编写一个小测试应用程序并删除不必要的部分:
import asyncio
import aioredis
async def reader(ch):
while (await ch.wait_message()):
msg = await ch.get_json()
print('Got Message:', msg)
i = int(msg['sleep_for'])
print('Sleep for {}'.format(i))
await asyncio.sleep(i)
print('End sleep')
async def main():
sub = await aioredis.create_redis(('localhost', 6379))
res = await sub.subscribe('chan:1')
ch1 = res[0]
tsk = await reader(ch1)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()
还有另一个测试应用程序,它发布带有sleep_for
字段的json blob,然后在订阅者应用程序中使用reader
语句在sleep
协程中模拟一些工作
我希望“睡觉”以“并行”方式运行,但实际上它们在屏幕上以同步的方式出现,只是一个接一个地出现。
我的猜测是,只要点击await ch.get_json(..)
(或者甚至是await ch.wait_message()
)行,我就能够处理下一条消息。在练习中,它像同步代码一样运行。我哪里错了?这可以使用连接池来处理,但这意味着有些东西不是异步的,也不知道到底是什么。
答案 0 :(得分:4)
我的猜测是,只要点击等待ch.get_json(..)(或者甚至可能等待ch.wait_message())行,我应该能够处理下一条消息。
这不是async/await
语法的工作原理。每当你在协程中点击await
时,该协程将被“暂停”,从而控制被叫协程。如果它正在睡觉,它不会自动处理下一条消息。
您应该使用ensure_future
在单独的协程中处理每条消息:
import asyncio
import aioredis
async def handle_msg(msg):
print('Got Message:', msg)
i = int(msg['sleep_for'])
print('Sleep for {}'.format(i))
await asyncio.sleep(i)
print('End sleep')
async def reader(ch):
while (await ch.wait_message()):
msg = await ch.get_json()
asyncio.ensure_future(handle_msg(msg))
async def main():
sub = await aioredis.create_redis(('localhost', 6379))
res = await sub.subscribe('chan:1')
ch1 = res[0]
tsk = await reader(ch1)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()