Myronaz
Myronaz

Reputation: 173

Implementing a while loop without interrupting the bot's main event loop

I am in the middle of having two of my bots interfacing with each other via a ZMQ server, unfortunately that also requires a second loop for the receiver, so i started looking around the web for solutions and came up with this:

async def interfaceSocket():
    while True:
        message = socket.recv()
        time.sleep(1)
        socket.send(b"World")
    await asyncio.sleep(3)

@client.event
async def on_ready():
    print('logged in as:')
    print(client.user.name)

client.loop.create_task(interfaceSocket())
client.run(TOKEN)

I basically added the interfaceSocket function to the event loop as a task as another while loop so i can constantly check the socket receiver while also checking the on_message listener from the discord bot itself but for some reason, the loop still interrupts the main event loop. Why is this?

Upvotes: 1

Views: 371

Answers (1)

user4815162342
user4815162342

Reputation: 155580

Although interfaceSocket is technically a task, it doesn't await anything in its while loop and uses blocking calls such as socket.recv() and time.sleep(). Because of that it blocks the whole event loop while it waits for something to happen.

If socket refers to a ZMQ socket, you should be using the ZMQ asyncio interface, i.e. use zmq.asyncio.Context to create a zmq.asyncio.Socket instead of. Then interfaceSocket can use await and become a well-behaved coroutine:

async def interfaceSocket():
    while True:
        message = await socket.recv()
        await asyncio.sleep(1)
        await socket.send(b"World")

Upvotes: 2

Related Questions