Search code examples
pythonmultithreadingflaskabort

Abort all running functions in a Flask application


I am using Flask to develop a Blockchain-based app and I need an end-point function that when called, all the running functions should be aborted. For example:

import sys
import flask
import time

app = flask.Flask(__name__)

@app.route("/infi1")
def infi1():
    while True:
        print("infi1")
        time.sleep(1)

@app.route("/infi2")
def infi2():
    while True:
        print("infi2")
        time.sleep(1)

@app.route("/abort")
def abort_funcs():
    # when this function is called, all the running functions should be aborted
    ''' code to stop 
    all running functions '''
    pass

@app.route("/")
def index():
    return flask.request.remote_addr

app.run(host="0.0.0.0", port=8080)

I will first run infi1() and infi2() so my application will print two messages indefinitely -

curl -X GET http://localhost:8080/infi1
curl -X GET http://localhost:8080/infi2

$ python d.py 
 * Serving Flask app "d" (lazy loading)
 * Environment: production
   WARNING: Do not use the development server in a production environment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://0.0.0.0:8080/ (Press CTRL+C to quit)
infi1
infi1
infi1
infi1
infi1
infi2
infi1
infi2
infi1
infi2
infi1
infi2
infi1
infi2
infi1

But I want these two functions to abort when I make a GET request to /abort.

Is it possible to do this in a flask app? I know I can use thread events or flags but then there will be so many checkpoints for if/while conditions in my app.

Thanks!


Solution

  • You should use an asynchronous framework/server. Synchronous servers like Flask are only meant to do one thing at a time, so the abort_funcs view won't be processed until the currently running one completes (which is never in your example, since they are infinite loops).

    If your program appears to be handling multiple requests at once, it is probably because you are using some server in front of it that is spawning multiple processes, but those processes are still isolate and can each only handle one view at a time.

    With an asynchronous server you can have those view kick off the infinite loop in a background thread and wait on them to return a response. Another option would be running those long loops in a task queue (e.g. Celery), but that will remove the possibility for those tasks to return the view response directly.