私はTornado Webアプリケーションを持っていますが、このアプリケーションはクライアントからGETおよびPOSTリクエストを受け取ることができます。Tornadoアプリケーションで複数のリクエストを受信する方法
POSTリクエストはTornado Queueで受け取った情報を入れてから、キューからこの情報をポップし、データベースで操作します。この操作は非常に遅く、完了するまでに数秒かかることがあります。
その間、このデータベース操作は、他のPOST(キューに他の情報を入れる)とGETを受け取ることができるようにしたいと考えています。代わりにGETは非常に高速であり、結果を即座にクライアントに返さなければなりません。
問題は、キューからポップして低速操作を開始すると、サーバーがクライアントからの他の要求を受け入れないということです。どうすれば解決できますか?私は、行の5 POSTをすれば、それは置いなぜ
# 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()
はまた、私は理解していない:
これは私がこれまで書いてきたsemplifiedコードです(インポートは、テキストの回避壁のために省略されています)待ち行列内の5つのデータは最大サイズは3ですが、
はい、私はpsycopg2を使用してデータベースにアクセスしています。私は 'ThreadPoolExecutor'を使用しようとしますが、これは今のところ最も簡単なことです。 質問:トルネード(momokoまたはクエリ)用のdbドライバを使用すると、 '_load_json_in_db'は常にコルーチンにする必要がありますか? – k4ppa
修正; I/Oを実行するTornadoアプリケーション内の関数は、非同期で記述する必要があります。つまり、コルーチンでなければならず、後でI/Oの結果で実行されるコールバックが必要です。 –