FoxGames01
FoxGames01

Reputation: 67

Two Asyncio Sleep at the same time

This is a very resumed version of my code, but works too. The problem is that i want to wait 2 seconds to send "pong", and at the same time wait 1 second to set msgPerSecond to 0. how i do that?

msgPerSecond = 0

async def on_message(self, message):
    if message.author == self.user or message.author.bot:
        return

    if message.content == 'ping':
        # Wait 2 seconds to send pong
        await asyncio.sleep(2)
        await message.channel.send('pong')

    msgPerSecond += 1
    print(f'msgPerSecond: {msgPerSecond}')

    # In 1 second reset msgPerSecond 
    await asyncio.sleep(1)
 
    msgPerSecond = 0
    print('msgPerSecond: 0')

Upvotes: 0

Views: 256

Answers (2)

FoxGames01
FoxGames01

Reputation: 67

I found the solution in case anyone was looking for it

If you are using Python version lower to 3.7, use asyncio.ensure_future instead of asnycio.create_task.

msgPerSecond = 0

async def on_message(self, message):
    if message.author == self.user or message.author.bot:
        return

    if message.content == 'ping':
        asyncio.create_task(send_pong())

    asyncio.create_task(set_MsgPerSecond())

    # Now all the functions with ensure_future method runs at the same time :D

async def send_pong():
    # Wait 2 seconds to send pong
    await asyncio.sleep(2)

    await message.channel.send('pong')

async def set_MsgPerSecond():
    msgPerSecond += 1
    print(f'msgPerSecond: {msgPerSecond}')

    # In 1 second reset msgPerSecond 
    await asyncio.sleep(1)

    msgPerSecond = 0
    print('msgPerSecond: 0')

Upvotes: 0

flakes
flakes

Reputation: 23634

I would restructure the code to have the msgPerSecond output in it's own loop and run this asynchronously to the pong logic. You can have a class to store the count of messages seen in each interval and print that value periodically.

class MessageMetrics:
    def __init__(self):
        self.count = 0

    def increment(self):
        self.count += 1

    async def report(self):
        while True:
            await asyncio.sleep(1)
            print(f'msgPerSecond: {self.count}')
            self.count = 0

Example usage:

metrics = MessageMetrics()


async def on_message():
    await asyncio.sleep(2)
    metrics.increment()
    await asyncio.sleep(2)
    metrics.increment()
    metrics.increment()
    metrics.increment()
    await asyncio.sleep(2)
    metrics.increment()
    metrics.increment()


async def main():
    metrics_task = asyncio.create_task(metrics.report())
    await on_message()
    await metrics_task


if __name__ == "__main__":
    asyncio.run(main())

Prints:

msgPerSecond: 0
msgPerSecond: 1
msgPerSecond: 0
msgPerSecond: 3
msgPerSecond: 0
msgPerSecond: 2
msgPerSecond: 0

Upvotes: 1

Related Questions