aio-libs / aiohttp-devtools

dev tools for aiohttp

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Runserver loop parameter

achernetsky opened this issue · comments

Hi.

If I use uvloop for my project as

asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())

and run runserver command and press ctrl+c, then I get an error

RuntimeError: Task <Task pending coro=<AppTask._run() running at /../lib/python3.6/site-packages/aiohttp_devtools/runserver/watch.py:48>> got Future <Future pending cb=[_chain_future.<locals>._call_check_cancel()]> attached to a different loop

Also, the server does not restart if I change the code.

Maybe, runserver command should take --loop parameter (for example --loop=uvloop) ?
Or already there is a solution to this problem?

Thanks.

Thanks for reporting, this should be fixed. It turned out the solution was very simple: just to switch around the order of importing the code and calling get_event_loop() so it gets the right loop.

The following works, it just requires that asyncio.set_event_loop_policy(uvloop.EventLoopPolicy()) is in module context so it's executed when the module is imported.

from aiohttp import web
import asyncio
import uvloop

async def handle(request):
    return web.Response(text='testing more')

asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())

app = web.Application()
app.router.add_get('/', handle)

@samuelcolvin, thanks a lot! Sorry, but I did not make it in time.

Now with you example, after press ctrl+c, I had this

[22:07:13] pre-check enabled, checking app factory
[22:07:13] Starting aux server at http://localhost:8001 ◆
[22:07:13] Starting dev server at http://localhost:8000 ●
^C[22:07:17] shutting down server...
Traceback (most recent call last):
  File "../venv/bin/adev", line 11, in <module>
    sys.exit(cli())
  File "../venv/lib/python3.6/site-packages/click/core.py", line 722, in __call__
    return self.main(*args, **kwargs)
  File "../venv/lib/python3.6/site-packages/click/core.py", line 697, in main
    rv = self.invoke(ctx)
  File "../venv/lib/python3.6/site-packages/click/core.py", line 1066, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "../venv/lib/python3.6/site-packages/click/core.py", line 895, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "../venv/lib/python3.6/site-packages/click/core.py", line 535, in invoke
    return callback(*args, **kwargs)
  File "../venv/lib/python3.6/site-packages/aiohttp_devtools/cli.py", line 88, in runserver
    run_app(*_runserver(**active_config))
  File "../venv/lib/python3.6/site-packages/aiohttp_devtools/runserver/main.py", line 26, in run_app
    loop.run_until_complete(app.shutdown())
  File "uvloop/loop.pyx", line 1203, in uvloop.loop.Loop.run_until_complete (uvloop/loop.c:25636)
  File "../venv/lib/python3.6/site-packages/aiohttp/web.py", line 271, in shutdown
    yield from self.on_shutdown.send(self)
  File "../venv/lib/python3.6/site-packages/aiohttp/signals.py", line 51, in send
    yield from self._send(*args, **kwargs)
  File "../venv/lib/python3.6/site-packages/aiohttp/signals.py", line 17, in _send
    yield from res
  File "../venv/lib/python3.6/site-packages/aiohttp_devtools/runserver/watch.py", line 107, in close
    await self._loop.run_in_executor(None, self.stop_process)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/concurrent/futures/thread.py", line 55, in run
    result = self.fn(*self.args, **self.kwargs)
  File "../venv/lib/python3.6/site-packages/aiohttp_devtools/runserver/watch.py", line 104, in stop_process
    logger.warning('server process already dead, exit code: %d', self._process.exitcode)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/logging/__init__.py", line 1318, in warning
    self._log(WARNING, msg, args, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/logging/__init__.py", line 1442, in _log
    self.handle(record)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/logging/__init__.py", line 1452, in handle
    self.callHandlers(record)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/logging/__init__.py", line 1514, in callHandlers
    hdlr.handle(record)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/logging/__init__.py", line 863, in handle
    self.emit(record)
  File "../venv/lib/python3.6/site-packages/aiohttp_devtools/logs.py", line 26, in emit
    log_entry = self.format(record)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/logging/__init__.py", line 838, in format
    return fmt.format(record)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/logging/__init__.py", line 575, in format
    record.message = record.getMessage()
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/logging/__init__.py", line 338, in getMessage
    msg = msg % self.args
TypeError: %d format: a number is required, not NoneType
Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x10db8fef0>
Task exception was never retrieved
future: <Task finished coro=<AppTask._run() done, defined at ../venv/lib/python3.6/site-packages/aiohttp_devtools/runserver/watch.py:45> exception=TypeError("can't pickle Loop objects",)>
Traceback (most recent call last):
  File "../venv/lib/python3.6/site-packages/aiohttp_devtools/runserver/watch.py", line 46, in _run
    await self._loop.run_in_executor(None, self._start_process)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/concurrent/futures/thread.py", line 55, in run
    result = self.fn(*self.args, **self.kwargs)
  File "../venv/lib/python3.6/site-packages/aiohttp_devtools/runserver/watch.py", line 90, in _start_process
    self._process.start()
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/multiprocessing/process.py", line 105, in start
    self._popen = self._Popen(self)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/multiprocessing/context.py", line 223, in _Popen
    return _default_context.get_context().Process._Popen(process_obj)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/multiprocessing/context.py", line 284, in _Popen
    return Popen(process_obj)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/multiprocessing/popen_spawn_posix.py", line 32, in __init__
    super().__init__(process_obj)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/multiprocessing/popen_fork.py", line 20, in __init__
    self._launch(process_obj)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/multiprocessing/popen_spawn_posix.py", line 47, in _launch
    reduction.dump(process_obj, fp)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/multiprocessing/reduction.py", line 60, in dump
    ForkingPickler(file, protocol).dump(obj)
TypeError: can't pickle Loop objects

is this using master now, eg. with #150 merged? What OS are you one?

I've released 0.6.1 it will take some time to be released because it's behind aiohttp in the build queue, but once release please install it and see if you're getting the same error.

I ran example on macOS High Sierra version 10.13 (17A405).
I checked on master (before I checked on uvloop-support branch) and got the same result.
I installed aiohttp-devtools as

$ pip uninstall aiohttp-devtools
Uninstalling aiohttp-devtools-0.6.1
...
$ pip install https://github.com/aio-libs/aiohttp-devtools/archive/master.zip

And ran the app as

$ PYTHONASYNCIODEBUG= adev runserver --root test

where test/main.py

from aiohttp import web
import asyncio
import uvloop

async def handle(request):
    return web.Response(text='testing more')

asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())

app = web.Application()
app.router.add_get('/', handle)

yes, I get the same error, looking at it now, I've created #153 because this it's a different error.