'What is the simple way to run a non-blocking coroutine?

In Go language, running another task in non-blocking way is pretty simple.

import "net/http"

func Call(request http.Request) http.Response {
    response := getResponse(request)
    go doTask(request)  // Non-blocking. No need to wait for result.
    return response
}

func getResponse(request http.Request) http.Response {
    // Do something synchronously here
    return http.Response{}
}

func doTask(r http.Request) {
    // Some task which takes time to finish
}

How can I achieve this in python?

I tried like this:

import asyncio
import threading
from asyncio.events import AbstractEventLoop

loop: AbstractEventLoop

def initialize():
    global loop
    loop = asyncio.new_event_loop()
    thread = threading.Thread(target=run_event_loop)
    thread.start()

def run_event_loop():
    loop.run_forever()

def call(request):
    response = get_response(request)

    # This should not block
    asyncio.run_coroutine_threadsafe(do_task(request), loop)

    return response

def get_response(r):
    # Do something synchronously here
    return 42

async def do_task(r):
    # Some task which takes time to finish
    return

This works, but it is kind of cumbersome.

Besides, the python code only make use of one thread for tasks, while Go automatically dispatches tasks to multiple processes (and so does Kotlin).

Is there better way?



Solution 1:[1]

We can run non-blocking tasks by using the concurrent.futures module. The ThreadPoolExecutor object is used for this purpose. You could modify your code to use this approach by making the following adjustments:

from concurrent.futures import ThreadPoolExecutor


def call(request):
    response = get_response(request)

    with ThreadPoolExecutor(max_workers=4) as e:
        e.submit(do_task)

    return response

def get_response(r):
    # Do something synchronously here
    return 42

async def do_task(r):
    # Some task which takes time to finish
    return

response would be returned instantly and do_task would run after the result is returned.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 JovanToroman