Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make function not to wait for other function inside it

Tags:

I have a flask service as below:

from flask import Flask, request
import json
import time


app = Flask(__name__)

@app.route("/first", methods=["POST"])
def main():
    print("Request received")

    func1()

    return json.dumps({"status": True})


def func1():
    time.sleep(100)
    print("Print function executed")


if __name__ == "__main__":
    app.run("0.0.0.0", 8080)

So now when I make a request using http://localhost:8080/first

  • control goes to main method and it prints Request received and wait for func1 to get executed and then it returns {"status": True}

But now I don't want to wait for func1 to finish its execution instead it will sent {"status": True} and func1 will continue it's execution.

like image 683
Sociopath Avatar asked Dec 06 '19 12:12

Sociopath


1 Answers

In order to reply to request from flask, you need the decorated function to finish (in your case, that's main).

If you want to execute something in parallel, you need to execute it in another thread or a process. Multi-process apps are used to achieve more than a single CPU. (CPU bound); in your case, you just need it to execute in parallel so it is better to go with threads.

A simple technique is to use ThreadPool. import ThreadPoolExecutor from concurrent.futures, then submit work to it, which allows your function execution code to continue. Try this:

from flask import Flask, request
import json
import time
import os
from concurrent.futures import ThreadPoolExecutor


app = Flask(__name__)


# Task manager executor
_threadpool_cpus = int(os.cpu_count() / 2)
EXECUTOR = ThreadPoolExecutor(max_workers=max(_threadpool_cpus, 2))


@app.route("/first", methods=["POST"])
def main():
    print("Request received")
    EXECUTOR.submit(func1)
    return json.dumps({"status": True})


def func1():
    time.sleep(2)
    print("Print function executed")


if __name__ == "__main__":
    app.run("0.0.0.0", 8080)

This will run the func1 in a different thread, allowing flask to respond the user without blocking until func1 is done.

like image 122
Chen A. Avatar answered Nov 02 '22 11:11

Chen A.