我有一个Tornado Web应用程序,此应用程序可以从客户端接收GET和POST请求。如何在Tornado应用程序中接收多个请求
POSTs请求会在Tornado队列中收到一条信息,然后我从队列中弹出这个信息,并用它对数据库进行操作,该操作可能非常缓慢,可能需要几秒钟才能完成!
在此期间,数据库操作继续我希望能够接收其他POST(将其他信息放入队列中)和GET。 GET的速度非常快,必须立即返回客户端的结果。
问题是,当我从队列中弹出并且慢速操作开始时,服务器不接受来自客户端的其他请求。我该如何解决这个问题?
这是semplified代码到目前为止我已经写了(进口,省略了文本的避免墙体):
# URLs are defined in a config file
application = tornado.web.Application([
(BASE_URL, Variazioni),
(ARTICLE_URL, Variazioni),
(PROMO_URL, Variazioni),
(GET_FEEDBACK_URL, Feedback)
])
class Server:
def __init__(self):
http_server = tornado.httpserver.HTTPServer(application, decompress_request=True)
http_server.bind(8889)
http_server.start(0)
transactions = TransactionsQueue() #contains the queue and the function with interact with it
IOLoop.instance().add_callback(transactions.process)
def start(self):
try:
IOLoop.instance().start()
except KeyboardInterrupt:
IOLoop.instance().stop()
if __name__ == "__main__":
server = Server()
server.start()
class Variazioni(tornado.web.RequestHandler):
''' Handle the POST request. Put an the data received in the queue '''
@gen.coroutine
def post(self):
TransactionsQueue.put(self.request.body)
self.set_header("Location", FEEDBACK_URL)
class TransactionsQueue:
''' Handle the queue that contains the data
When a new request arrive, the generated uuid is putted in the queue
When the data is popped out, it begin the operation on the database
'''
queue = Queue(maxsize=3)
@staticmethod
def put(request_uuid):
''' Insert in the queue the uuid in postgres format '''
TransactionsQueue.queue.put(request_uuid)
@gen.coroutine
def process(self):
''' Loop over the queue and load the data in the database '''
while True:
# request_uuid is in postgres format
transaction = yield TransactionsQueue.queue.get()
try:
# this is the slow operation on the database
yield self._load_json_in_db(transaction)
finally:
TransactionsQueue.queue.task_done()
而且我不明白为什么,如果我做一排5 POST,它把尽管最大尺寸是3,但队列中的所有五个数据都是3.
是的,我使用psycopg2来访问数据库。我会尝试使用'ThreadPoolExecutor',这似乎是现在最简单的事情。 问题:如果我使用数据库驱动程序龙卷风(momoko或查询)'_load_json_in_db'必须永远是一个协程? – k4ppa
正确;在I/O的Tornado应用程序中的任何函数都必须异步写入:也就是说,它必须是一个协程,或者它必须采用稍后执行的I/O结果的回调函数。 –