Tornado: There is no current event loop in thread 'Thread-5'

Created on 4 Nov 2018  路  5Comments  路  Source: tornadoweb/tornado

hi,

i have a tornado websocket handler, and in async def on_message(...) i want to call a long running function with loop.run_in_executor(...), so i call asyncio.get_event_loop(), but this throws the exception:

RuntimeError: There is no current event loop in thread 'Thread-5'.

but i don't understand this, because my application is a simple, single-threaded application, and there must be an even loop running for on_message(...) to be called. if i call print(threading.current_thread().name) from on_message(), i get MainThread.

to begin the io loop in the first place, i just go:

loop = asyncio.get_event_loop()  # this `.get_event_loop()` works!
...
print(threading.current_thread().name)  # this also outputs `MainThread`
...
loop.run_forever()

i've read up on other issues like this, but they all seem to do unusual things with threads, like this one.

what am i doing wrong?

with thanks

Most helpful comment

  1. loop.run_in_executor essentially uses a thread or process pool to perform tasks. That's why your error occurs in the non-main thread.

  2. The default asyncio event loop policy only automatically creates event loops in the main threads. Other threads must create event loops explicitly. That's why your non-main thread doesn't have an event loop.

You can solve your problem by executing the following code before starting ioloop:

from tornado.platform.asyncio import AnyThreadEventLoopPolicy
asyncio.set_event_loop_policy(AnyThreadEventLoopPolicy())

All 5 comments

  1. loop.run_in_executor essentially uses a thread or process pool to perform tasks. That's why your error occurs in the non-main thread.

  2. The default asyncio event loop policy only automatically creates event loops in the main threads. Other threads must create event loops explicitly. That's why your non-main thread doesn't have an event loop.

You can solve your problem by executing the following code before starting ioloop:

from tornado.platform.asyncio import AnyThreadEventLoopPolicy
asyncio.set_event_loop_policy(AnyThreadEventLoopPolicy())

AnyThreadEventLoopPolicy will make this error go away, but it doesn't sound like it's what you want. You say you only want one event loop, on the main thread, which works by default. Are you sure that you're getting this error before you call run_in_executor instead of from the function that is running inside the executor? Inside the executor, you can't use the event loop.

hi,

loop.run_in_executor essentially uses a thread or process pool to perform tasks. That's why your error occurs in the non-main thread.

in both locations that i call .get_event_loop() (one that works, one that fails), i have confirmed that both are running in the MainThread (with print(threading.current_thread().name)). (i'm aware of that rookie mistake, and am confident i'm not making it).

since posting, i've read somewhere that this is an issue with python 3.5.2, and updating makes it go away - i'll try this soon.

with thanks

oh no, this is my bad. it is the rookie mistake. the run_in_executor() function was calling a callback. i thought it was my call to get_event_loop() which was causing the issue, but i apparently didn't read the stacktrace carefully enough.

with thanks

@gagern I'm getting this error within my .run_on_executor and no any other callback:

class MyHandler(BaseHandler):
    executor = BoundedThreadPoolExecutor(max_workers=5)

    def post(self, *args):
        pass

    @tornado.concurrent.run_on_executor
    def get(self, *args):
       # my code running on the current thread

Shall I use the policy?

from tornado.platform.asyncio import AnyThreadEventLoopPolicy
asyncio.set_event_loop_policy(AnyThreadEventLoopPolicy())
Was this page helpful?
0 / 5 - 0 ratings