preface
Sometimes we may encounter such a situation. We have a function that provides an http interface. We need to send a request to the http interface to start the service, but the service function may be executed for a long time. In this way, if the request result is returned after the function is executed, the request may timeout.
client
import requests req = requests.get("http://127.0.0.1:9898/register?username=aaa&pwd=232323") print(req.content)
Server
# coding=utf-8 import flask from flask import jsonify from flask import request from gevent import pywsgi import sys reload(sys) import time sys.setdefaultencoding('utf-8') server = flask.Flask(__name__) @server.route('/register', methods=['get', 'post']) def registerPost(): # The post request obtains the parameters of the request, and the return result type is str username = request.values.get('username') pwd = request.values.get('pwd') app_id = request.values.get('app_id') dowork(app_id) # confirmpwd = request.values.get('confirmpwd') if username and pwd: # Judge whether the user name, password and confirmation password entered are not empty return ("User name is:%s, Password is:%s" % (username, pwd)) else: return jsonify({"code": 504, "msg": "Required item cannot be blank"}) if __name__ == '__main__': # Port can be specified. The default port is 5000 # The default host is 127.0.0.1. If it is written as 0.0.0.0, others can access it, which means listening to multiple network cards, # server.run(debug=True, port=9898, host='0.0.0.0') server = pywsgi.WSGIServer(('0.0.0.0', 9898), server) server.serve_forever()
This is a typical synchronous return result. After the request is initiated, the request result can only be returned after the dowork() function is executed. If the dowork() execution time is long, the client request will timeout
At this time, we may need an asynchronous http interface. After receiving the request from the client, we will immediately return a request result, and then slowly execute the task to be executed. How to realize this process? My method is to realize it through multithreading. In the response function of the server, we will receive a request every time and obtain the parameters carried in the request, Then use these parameters to create a thread that will execute our function service, and finally return the request result, so that the client can quickly obtain the request result, so as not to make the client request timeout
The following is the response function of the server added with thread
# coding=utf-8 import flask from flask import jsonify from flask import request from gevent import pywsgi import sys reload(sys) import time sys.setdefaultencoding('utf-8') server = flask.Flask(__name__) import threading import time exitFlag = 0 class myThread (threading.Thread): def __init__(self, threadID, name, counter, app_id): threading.Thread.__init__(self) self.threadID = threadID self.name = name self.counter = counter self.app_id = app_id def run(self): print ("Start thread:" + self.name) print_time(self.name, self.counter, 1, self.app_id) print ("Exit thread:" + self.name) def print_time(threadName, delay, counter, app_id): while counter: if exitFlag: threadName.exit() time.sleep(delay) print ("%s: %s" % (threadName, time.ctime(time.time()))) dowork(app_id) counter -= 1 @server.route('/register', methods=['get', 'post']) def registerPost(): # The post request obtains the parameters of the request, and the return result type is str username = request.values.get('username') pwd = request.values.get('pwd') app_id = request.values.get('app_id') # Create a new thread thread1 = myThread(1, "Thread-1", 1, app_id) # Start a new thread thread1.start() # confirmpwd = request.values.get('confirmpwd') if username and pwd: # Judge whether the user name, password and confirmation password entered are not empty return ("User name is:%s, Password is:%s" % (username, pwd)) else: return jsonify({"code": 504, "msg": "Required item cannot be blank"}) if __name__ == '__main__': # Port can be specified. The default port is 5000 # The default host is 127.0.0.1. If it is written as 0.0.0.0, others can access it, which means listening to multiple network cards, # server.run(debug=True, port=9898, host='0.0.0.0') server = pywsgi.WSGIServer(('0.0.0.0', 9898), server) server.serve_forever()
Because the thread's run() method and start() method cannot pass parameters, if we need to obtain parameters from the request and pass them to the function to be executed, we can add the parameters we need to pass to the parameters of the thread's construction method, so that we can dynamically obtain the parameters passed in the request inside the run() method