RuntimeError when using two event loops
iAnanich opened this issue · comments
Steps to reproduce
requirements.txt
# Python 3.5.2
aiohttp==2.1.0
async-timeout==1.2.1
chardet==3.0.4
gunicorn==19.7.1
multidict==2.1.6
yarl==0.10.3
- code in
test.py
:
import asyncio
import async_timeout
from aiohttp import web
asyncio.set_event_loop(asyncio.new_event_loop())
class A:
async def am(self):
with async_timeout.timeout(timeout=1):
await asyncio.sleep(0.5)
class B:
a = A()
async def bm(self):
await self.a.am()
b = B()
async def hello(request):
await b.bm()
return web.Response(text="Hello, world")
app = web.Application()
app.router.add_get('/', hello)
-
run this command
gunicorn test:app --worker-class aiohttp.GunicornWebWorker -b 127.0.0.1:8000
-
make request to
https://127.0.0.1:8000/
URL.
Get RuntimeError: Timeout context manager should be used inside a task
error message.
question
Why in this case async_timeout
class have been initialised with developer-defined event loop instead gunicorn-defined (aiohttp.GunicornWebWorker
)? How can library provide more informative message to help developer understand why it isn't working?
But your example works as expected!
@asvetlov I need some time to find out why it was an error...
But your example works as expected!
What do you mean "expected"?
http://127.0.0.1:8000
URL throws 500 HTTP code and prints in console RuntimeError: Timeout context manager should be used inside a task
error.
Maybe you are using another package version? I have updated first post with requirements.
Your example works in new environment with versions specified in requirements.txt
.
The only difference I have Python 3.5.3
Anyway, what text are you suggesting?
Current words describe situation when context manager is used from regular callback, tornado's callback or if the loop was not running.
@asvetlov I'm not fully understand what is callback
. Please, help me understand.
I just doesn't understand why it have raised an error (as I understand, timeout
class must call asyncio.get_event_loop
at initialisation and store the result in _loop
attribute to use it on __entry__
method call, and it gets initialised when A.am
method called which heppens when I make request to http://127.0.0.1:8000/
URl). And my suggestiongs for the text are dependend on previous "why" question.
Because the best error message must tell me what line of code is wrong. But in the reality it isn't possible and I expect just helpfull message that points me at problem. In this case, when using 3.5.2, it isn't for me, because in my head context manager is inside coroutine method, executed inside event loop. But if it is fixed in Python 3.5.3, and everyone can use asyncio.get_event_loop
, thats no problem.