Olof
Olof

Reputation: 797

Runtime error: Event loop is running

I get the following error when I call the function send_message.

Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/lib/python3.4/threading.py", line 920, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.4/threading.py", line 868, in run
    self._target(*self._args, **self._kwargs)
  File "/home/joffe/Documents/discord/irc/ircbot.py", line 44, in get_message
    mydiscord.send_message(line[1])
  File "/home/joffe/Documents/discord/irc/mydiscord.py", line 37, in send_message
    client.loop.run_until_complete(client.send_message(SERVER,message))
  File "/usr/lib/python3.4/asyncio/base_events.py", line 331, in run_until_complete
    self.run_forever()
  File "/usr/lib/python3.4/asyncio/base_events.py", line 296, in run_forever
    raise RuntimeError('Event loop is running.')
RuntimeError: Event loop is running.

My function send_message takes a message and sends it to a discord channel. The function is called from a function that is running in a thread. The client object is created in the main thread.

def send_message(message):
    print(str.encode("Message to discord: " + message))

    client.loop.run_until_complete(client.send_message(SERVER,message))

Upvotes: 13

Views: 10053

Answers (1)

Sean
Sean

Reputation: 365

The "Event loop is running" exception indicates you called loop.run_until_complete on a loop that is already running, perhaps in another thread.

  1. If the loop is already running in another thread and you want to submit a coroutine for it to execute, use:

    asyncio.run_coroutine_threadsafe(client.send_message(SERVER, message), client.loop)
    
  2. If you are trying to add a coroutine to the loop and that loop is running on the current thread, then the best way is probably to just await/yield from it

  3. If you're scheduling it from a synchronous function, then you probably want:

    asyncio.ensure_future(
        client.send_message(SERVER, message),
        loop=client.loop
    ).add_done_callback(fn)
    

    Where fn is a function whose only parameter is the future that is created by ensure_future and which is called after the future is completed.

Upvotes: 20

Related Questions