aio-libs / aiohttp-devtools

dev tools for aiohttp

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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.