问题
I currently have a route in a Flask app that pulls data from an external server and then pushes the results to the front end. The external server is occasionally slow or unresponsive. What's the best way to place a timeout on the route call, so that the front end doesn't hang if the external server is lagging? Or is there a more appropriate way to handle this situation in Flask (not Apache, nginx, etc)?
My goal is to timeout a route call, not keep an arbitrary long process alive like this SO question: Time out issues with chrome and flask. Options like websockets run background processes/threads until they finish; however, I want to stop a slow route call after some fixed amount of time has elapsed. Like Timeout on a function call and Python Timeout but within a Flask context. Celery's task decorator (Concurrent asynchronous processes with Python, Flask and Celery) seems like a great solution, but I don't want to require a large dependency to only use a small amount of its functionality.
回答1:
Not entirely sure if I'm right about all this, but my understanding is that if the thread (or greenthread) handling the request does the network call in it's own "foreground", and that call times out, the borken pipe is pretty much going to happen. But what you can do is spin off a fully-separate thread that does the network request, then call Thread.join() with a timeout in your request-handling code.
http://docs.python.org/2/library/threading.html#threading.Thread.join
At that point, call Thread.isAlive() (still in your request-handling code path) and if True, the network call didn't return in time, and you return your error state.
If it's False - and you'll need to have the "worker" thread update some (thread-safe) data structure with the response data - you get that response data and go on your way.
来源:https://stackoverflow.com/questions/18164393/place-a-timeout-on-calls-to-an-unresponsive-flask-route-updated