I am having a problem similar to the one in this question. I have a flask application that takes input from the user (sometimes multiple thousand addresses), then processes it (cleans/geocodes), then returns a results page after everything is done. During this time, the page remains loading. This loading time could potentially be up to 15 minutes, depending on the size of the input. The application can process roughly 300 address per minute.
I saw one of the answers say that it could potentially be solved by putting all of the work on a separate process and redirecting the user to sort of a 'Loading Please Wait' page, and then after that is complete, redirect the user to the results page.
I was wondering what all of this would entail.
Here is a simplified version of my code, excluding import statements etc.: (I am currently using gunicorn to serve the application)
app = Flask(__name__)
@app.route("/app")
def index():
return """
<form action="/clean" method="POST"><textarea rows="25" cols="100"
name="addresses"></textarea>
<p><input type="submit"></p>
</form></center></body>"""
@app.route("/clean", methods=['POST'])
def dothing():
addresses = request.form['addresses']
return cleanAddress(addresses)
def cleanAddress(addresses):
....
....
.... processes each address 1 by 1,
.... then adds it to list to return to the user
....
....
return "\n".join(cleaned) #cleaned is the list containing the output
I was told that Celery
could be used to help me do this.
Here is my current attempt with Celery. I am still getting the same error where the page times out, however like usual, from the console I can see that the application is still working...
app = Flask(__name__)
app.config['CELERY_BROKER_URL'] = 'redis://0.0.0.0:5000'
app.config['CELERY_RESULT_BACKEND'] = 'redis://0.0.0.0:5000'
celery = Celery(app.name, broker = app.config['CELERY_BROKER_URL'])
celery.conf.update(app.config)
@app.route("/clean", methods=['POST'])
def dothing():
addresses = request.form['addresses']
return cleanAddress(addresses)
@celery.task
def cleanAddress(addresses):
....
....
.... processes each address 1 by 1,
.... then adds it to list to return to the user
....
....
return "\n".join(cleaned) #cleaned is the list containing the output
After the application finishes running, I am given this console error:
Traceback (most recent call last):
File "/home/my name/anaconda/lib/python2.7/SocketServer.py", line 596, in process_request_thread
self.finish_request(request, client_address)
File "/home/my name/anaconda/lib/python2.7/SocketServer.py", line 331, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "/home/my name/anaconda/lib/python2.7/SocketServer.py", line 654, in __init__
self.finish()
File "/home/my name/anaconda/lib/python2.7/SocketServer.py", line 713, in finish
self.wfile.close()
File "/home/my name/anaconda/lib/python2.7/socket.py", line 283, in close
self.flush()
File "/home/my name/anaconda/lib/python2.7/socket.py", line 307, in flush
self._sock.sendall(view[write_offset:write_offset+buffer_size])
error: [Errno 32] Broken pipe