Home > Back-end >  How can i create a task, that checks for real-time changes on a list?
How can i create a task, that checks for real-time changes on a list?

Time:10-31

I have a problem that I'm not very sure how I could make that. I tried my best at searching but have no clue (aside from a while True task) how I could do that, what I want. So I have currently a list with messages that my python bot needs to transfer from Server X to many others (like a queue system).

So what should my task do? I need something like a "live" (async) task which checks every time for new entries in the list. If nothing is in the list anymore, it should wait for new items. I tried a while True: task, but I think that's not a great idea for the performance of my bot.

That's my current function for view/editing the queue:

global_queue = []

async def Queue(action=None, globalmsg=None, original=None, code=None):

    if action is not None:
        if action == "add":
            global_queue.append((globalmsg, original, code))

        elif action == "remove":
            global_queue.remove((globalmsg, original, code))

    else:
        return global_queue

And that is my while True: task, which is I think not very effective for my bot performance, I can't even start the bot without an await asyncio.sleep().

def __init__(self, client):
    self.client = client

    client.loop.create_task(self.on_queue())

async def on_queue(self):
    await self.client.wait_until_ready()

    while True:
        await asyncio.sleep(1)

        queue = await Queue()
        if len(queue) >= 1:
           await Queue("remove", item[0], item[1], item[2])
           # do something

So how can I get away from the while True: task and can use more efficient way? Important Reminder: Because it's a queue system, it should not be possible to run the task twice.

CodePudding user response:

What you are looking for is queue!

Use ayncio.Queue instead of a list.

To create the queue use:

queue = asyncio.Queue()

To put an item in the queue use:

await queue.put(item)

to get and remove an item from the queue:

item = await queue.get()

or just

await queue.get()

if you dont need the item

if the queue is empty then the task is suspended until there is some item. If you want the queue to have a max size, pass the max size as the argument to the constructor. Then if the queue is full the put() call also suspend the task until there is space in the queue.

You can read the asyncio documentation but it is not very friendly. I'd go for some tutorial.

  • Related