Обработка нескольких POST-запросов одновременно в Python 2.7 - PullRequest
0 голосов
/ 27 марта 2019

У меня есть сервер торнадо, прослушивающий порт 6789 для запросов POST на "/train" и "/predict". Поезд метод может занять до 3 часов, в то время как прогноз может вернуться через 2 минуты. Я хочу, чтобы они обрабатывались одновременно. Таким образом, даже когда «/ train» работает, если поступает POST-запрос для «/ предиката», он может обрабатывать это одновременно и возвращать свой вывод, не дожидаясь завершения «/ train».

Я пытался использовать ThreadPool, но он по-прежнему не работает одновременно.

Мой настоящий код выглядит следующим образом. Он функционирует, но если сделан запрос на обучение, а затем выполнен запрос на предсказание. Он ожидает завершения поезда, прежде чем обрабатывать прогноз. Предположим, присутствуют функции поезда и прогнозирования, и они не принимают никаких параметров.

import logging
import time
import threading
from multiprocessing.pool import ThreadPool
import flask
from tornado import wsgi, httpserver, ioloop
from flask import Flask
from train_script import train
from predict_script import predict
app = Flask(__name__)


@app.route("/train", methods=['POST'])
def train_run():
    payload = flask.request.get_json(silent=True)
    if payload is not None:
        try:
            async_result = pool.apply_async(train)
            response = async_result.get() 
            resp = flask.jsonify(response)
            resp.status_code = 200
        except Exception as ex:
            resp = flask.jsonify({"status": "Failure"})
            resp.status_code = 500
    else:
        resp = flask.jsonify({"status": "Failure"})
        resp.status_code = 500
    return resp

@app.route("/predict", methods=['POST'])
def predict_run():
    payload = flask.request.get_json(silent=True)
    if payload is not None:
        try:
            async_result = pool.apply_async(predict)
            response = async_result.get() 
            resp = flask.jsonify(response)
            resp.status_code = 200
        except Exception as ex:
            resp = flask.jsonify({"status": "Failure"})
            resp.status_code = 500
    else:

        resp = flask.jsonify({"status": "Failure"})
        resp.status_code = 500
    return resp


if __name__ == "__main__":
    port = 6789
    http_server = httpserver.HTTPServer(wsgi.WSGIContainer(app))
    pool = ThreadPool(processes=10)# Expects max concurrent requests to be 10
    http_server.listen(port)
    logging.info("Tornado server starting on port {}".format(port))
    ioloop.IOLoop.instance().start()

1 Ответ

0 голосов
/ 28 марта 2019

Tornado's WSGIContainer не поддерживает какой-либо параллелизм.Либо используйте интерфейсы RequestHandler от Tornado без Flask или WSGI, либо используйте Flask с gunicorn или uwsgi.Вы практически ничего не получаете и много теряете, комбинируя Tornado со средами WSGI, поэтому это полезно только в определенных специализированных ситуациях.

...