I have a request coming through a function that has been decorated with @app.route('/url/path/to/view')
.
It does a couple of things to find some data and do some calculations, and during this the function runs normally. However, at the end I want to start a new process (from a python function, currently using multiprocessing.Process
). Once this process is started, I want the function to return, while the new process keeps running independently.
Pseudo-code for my current approach
def start_process(arguments):
# some code here that the process will run
p = multiprocessing.Process(target=start_process, args=(...))
p.start()
return app.response("{ 'status': 'ok' }", mimetype='application/json')
Will this approach work and can the Flask application continue running without affecting the new process?
Starting a subprocess with multiprocessing is perfectly acceptable. Here's a minimal working example that uses multiprocessing to update a database in the background. As Audrius states, eventually you'll probably want a proper task queue.
from flask import Flask, jsonify
import multiprocessing
import dataset
import time
import random
app = Flask(__name__)
DATABASE_URL = 'sqlite:///dev.db'
def add_person(name):
""" Add a person to the db. """
person = {'name': name, 'age': -1, 'status': 'processing'}
db = dataset.connect(DATABASE_URL)
db['people'].insert(person)
return True
def update_person(name):
""" Update a person in db with a fake long running process
that guesses a random age. """
time.sleep(10) # simulate a long running process
age = random.randint(1, 120)
person = {'name': name, 'age': age, 'status': 'finished'}
db = dataset.connect(DATABASE_URL)
db['people'].update(person, ['name'])
return True
def get_person(name):
""" Retrieve a person from the db. """
db = dataset.connect(DATABASE_URL)
person = db['people'].find_one(name=name)
return person
@app.route('/<name>')
def index(name):
""" Get person. If name not found, add_person to db and start update_person. """
if not get_person(name):
add_person(name)
thread = multiprocessing.Process(target=update_person, args=(name,))
thread.start()
person = get_person(name)
return jsonify(person)
if __name__ == '__main__':
app.run(debug=True)
Visit localhost:5000/bert
while the subprocess is running:
{
"status": "processing",
"age": -1,
"name": "bert",
"id": 1
}
Wait, then refresh and you'll see the subprocess has finished:
{
"status": "finished",
"age": 28,
"name": "bert",
"id": 1
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With