1

I want to implement async method in the following code:

import time

def main(num):
    num_list = []
    for i in range(num):
        num_list.append(i)
        print("The number that is added in list is:", i)
        time.sleep(2)
    return num_list


def count():
    start_time = time.time()
    num_list = [3,5,2,8,2]
    for i in num_list:
        print("\nIn count() = ", i)
        data = main(i)
        print("Got data from main() = ", data)
        time.sleep(2)
    total_time = time.time() - start_time
    print("The code took",total_time,"seconds to complete")

if __name__ == "__main__":
    count()

This code takes 50s to complete. I tried to implement async method in this code but I was not able to succeed because I just started learning about it. Can you tell me how can I implement async method in this code.

Here's the code where I tried to implement async method:

import asyncio, time
from asgiref.sync import sync_to_async

@sync_to_async
def main(num):
    num_list = []
    for i in range(num):
        num_list.append(i)
        print("The number that is added in list is:", i)
        time.sleep(2)
    return num_list

def get_data(data_var):
    try:
        data_var.send(None)
    except StopIteration as e:
        return e.value


async def count():
    start_time = time.time()
    num_list = [3,5,2,8,2]
    for i in num_list:
        print("In count() :".format(i))
        task1 = asyncio.ensure_future(main(i))
        data = get_data(main(i))
        print("In main() = {}".format(data))
        await asyncio.sleep(2)
        await task1
    total_time = time.time() - start_time
    print("The code took",total_time, "seconds to complete")

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

And I am not getting num_list as return value instead I am getting None.

1 Answer 1

1

If you can convert your main into async function, then it can be written as this.

import asyncio
import time
from loguru import logger


async def main(num):
    num_list = []
    for i in range(num):
        num_list.append(i)
        logger.info(f"The number that is added in list is: {i}")
        await asyncio.sleep(2)
    return num_list


async def count():
    start_time = time.time()
    num_list = [3,5,2,8,2]
    task_list = []
    for i in num_list:
        logger.info(f"In count() = {i}")
        task = asyncio.create_task(main(i))
        task_list.append(task)
    result_list = await asyncio.gather(*task_list)
    for r in result_list:
        logger.info(f"Got data from main() = {r}")
    total_time = time.time() - start_time
    logger.info(f"The code took {total_time} seconds to complete")

loop = asyncio.get_event_loop()
loop.run_until_complete(count())

If you can't convert the main function, threading is your best bet.

from concurrent.futures import ThreadPoolExecutor, as_completed
from loguru import logger

def main(num):
    num_list = []
    for i in range(num):
        num_list.append(i)
        logger.info(f"The number that is added in list is: {i}")
        time.sleep(2)
    return num_list


def count():
    start_time = time.time()
    num_list = [3,5,2,8,2]
    with ThreadPoolExecutor(max_workers=5) as executor:
        futures = {}
        for k in num_list:
            logger.info(f"In count() = {k}")
            futures[executor.submit(main, k)] = k
        for future in as_completed(futures):
            logger.info(f"Got data from main() = {future.result()}")
            time.sleep(2)
        total_time = time.time() - start_time
        logger.info(f"The code took {total_time} seconds to complete")

count()

Both will achieve the same goal in terms of overall execution time.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.