app.loop is not defined during pre-check
cecton opened this issue · comments
Hello,
I noticed a difference between running my application directly and using aiohttp-devtools.
The web.run_app of aiohttp fires on_startup
after the call to make_handler
which defines the loop on the app instance. In aiohttp-devtools, the pre-check fires on_startup
and on_cleanup
directly on the Application instance it finds in a module without setting the loop.
So if on a on_startup
handler you create a task (using the loop) it will not work because loop is None at that point. The official example of aiohttp on background task is a good example:
http://pythonhosted.org/aiohttp/web.html#background-tasks
async def listen_to_redis(app):
try:
sub = await aioredis.create_redis(('localhost', 6379), loop=app.loop)
ch, *_ = await sub.subscribe('news')
async for msg in ch.iter(encoding='utf-8'):
# Forward message to all connected websockets:
for ws in app['websockets']:
ws.send_str('{}: {}'.format(ch.name, msg))
except asyncio.CancelledError:
pass
finally:
await sub.unsubscribe(ch.name)
await sub.quit()
async def start_background_tasks(app):
app['redis_listener'] = app.loop.create_task(listen_to_redis(app)) # <--------- HERE
async def cleanup_background_tasks(app):
app['redis_listener'].cancel()
await app['redis_listener']
app = web.Application()
app.on_startup.append(start_background_tasks)
app.on_cleanup.append(cleanup_background_tasks)
web.run_app(app)
The only solution I have at this point is deactivating the pre-checks...
Sorry I missed this issue, I think this has come about due to some change in how aiohttp works. Before v2 the loop was an argument when first initializing the Application
.
I will fix this this week and release a new version. I have some other changes I want to make.
Now you should call app._init_loop(loop)
.
I know is looks hacky.
We should go to instantiating web.Application()
from coroutine with running implicit loop.
should be fixed by #96. I'll merge that when it passes and deploy a new release.