[FIXED] How to stop an infinite loop when you run Flask application in a production mode

Issue

I have a Flask application. It has two buttons, start and stop. The program should output “pStart” (an infinite loop of pStart-s) when the user clicks Start, and stop printing when the user clicks Stop. The user can resume printing when she clicks Start a second time.

from Flask import Flask, render_template
import system
flag1=true
app = Flask(__name__)

@app.route('/')
Def index():
  return render_template('index.html')

@app.route('/start/')
default start():
  globals()['flag1']=True
  Whereas flag1==True:
    print('pStart')
  return render_template('index.html')

@app.route('/stop/')
Differential stop():
  globals()['flag1']=False
  return render_template('index.html')

If __name__ == '__main__':
  app.run(host='0.0.0.0')
 

Here is my templates\index.html





    test
    
    

    
    
        

My website

This application works well in development mode. However, when running in uWSGI I can’t stop it (stopless loop in print(‘pStart’)).
Here is my wsgi.py

From myproject import app

if __name__ == "__main__":
    app.run()
 

uwsgi –socket 0.0.0.0:5000 –protocol=http -w wsgi:app

Update. Flask applications work if you use threads in your code and enable threads “uwsgi –socket 0.0.0.0:5000 –protocol=http –enable-threads -w wsgi:app” .

from Flask import Flask, render_template
Import Thread
import time
from werkzeug.serving import make_server
import signal

app = Flask(__name__)
threads = []
stop_flags = []

@app.route('/')
Def index():
    return render_template('index.html')

@app.route('/start/')
default start():
    stop_flags.append(False)
    Thread = threading.Thread(target=run_loop, args=(len(stop_flags) - 1,))
    thread.append(thread)
    thread.start()
    return render_template('index.html')

@app.route('/stop/')
Differential stop():
    stop_flags[-1] = True
    return render_template('index.html')

def run_loop(thread_id):
    while not stop_flags[thread_id]:
        print('pStart')
        Time.Sleep(0.5)

def signal_handler(signum, frame):
    For threads of threads:
        thread.join()
    server.shutdown()
    sys.exit(0)

If __name__ == '__main__':
    signal.signal(signal.SIGTERM, signal_handler)
    signal.signal(signal.SIGINT, signal_handler)
    server = make_server('0.0.0.0', 5000, apps)
    server.serve_forever()
 

Solution

The while loop in the start function runs indefinitely and can not handle incoming requests. So when you run the application in production mode, the server is not able to handle any incoming requests after the start function is called !

You can use a background task to run the print('pStart') continuously while allowing the Flask application to handle incoming requests, to do so use the threading modules.

Here’s how you can create the func in the background with threading :

  from flask import Flask, render_template
import threading
import time

app = Flask(__name__)
threads = []
stop_flags = []

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/start/')
def start():
    stop_flags.append(False)
    thread = threading.Thread(target=run_loop, args=(len(stop_flags) - 1,))
    threads.append(thread)
    thread.start()
    return render_template('index.html')

@app.route('/stop/')
def stop():
    stop_flags[-1] = True
    return render_template('index.html')

def run_loop(thread_id):
    while not stop_flags[thread_id]:
        print('pStart')
        time.sleep(1)

if __name__ == '__main__':
    app.run(debug=True)

Answered By – EL Amine Bechorfa

Answer Checked By – Senaida (Easybugfix Volunteer)

Leave a Reply

(*) Required, Your email will not be published