FrenchGap
FrenchGap

Reputation: 21

Python run multiple background loops independently

In one of my projects, I need to run three different database updater functions at different intervals. For instance, function one needs to run every 30 seconds, function two needs to run every 60 seconds and function 3 every 5 minutes (notably due to API call restrictions).

I've been trying to achieve this in python, looking up every possible solution but I cannot seem to find anything that works for my use case. I am rather fresh in python.

Here is (somewhat) what I have, using asyncio.

import asyncio

def updater1(url1, url2, time):
    print(f"Doing my thing here every {time} seconds")

def updater2(url1, url2, time):
    print(f"Doing my thing here every {time} seconds")

def updater3(url, time):
    print(f"Doing my thing here every {time} seconds")


async def func1():
    updater1(rankUrl, statsUrl, 30)
    await asyncio.sleep(30)


async def func2():
    updater2(rankUrl, statsUrl, 60)
    await asyncio.sleep(60)


async def func3():
    updater3(url, 300)
    await asyncio.sleep(300)


# Initiate async loops
while True:
    asyncio.run(func1())
    asyncio.run(func2())
    asyncio.run(func3())

The issue is that these tasks run one after each other, while what I am trying to achieve is that they run independently from each other, with a start time when the script is initiated, and respective to their own individual loop times

Any idea on how this could be done is much appreciated - I am open to new concepts and ideas if you have any for me to explore :)

Upvotes: 1

Views: 1646

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1123810

Don't use asyncio.run() on individual coroutines, as async.run() is itself not asynchronous. The call to asyncio.run() won't return until the funcN() coroutine is done.

Create a single top-level coroutine that then runs others as tasks:

async def main():
    task1 = asyncio.create_task(func1())
    task2 = asyncio.create_task(func2())
    task3 = asyncio.create_task(func3())

    await asyncio.wait([task1, task2, task3])

The above kicks off three independent tasks, then waits for all 3 to complete.

Upvotes: 3

Related Questions