Flask блокировка на конечной точке без разрешения вызовов другой конечной точки - PullRequest
2 голосов
/ 12 февраля 2020

Одна из конечных точек моего flask API делает длинный запрос к Live Stream. Вот пример кода:

@app.route('/stream')
def live_stream(sensor_id):
    stream = requests.get('stream_url', stream=True)
    return Response(stream_with_context(stream.iter_content(chunk_size=2048)),
                content_type=stream.headers['content-type'])

Этот маршрут работает нормально, и поток идет хорошо. Однако, когда я пытаюсь делать запросы к другим маршрутам, создается впечатление, что сервер застревает в этой конечной точке.

Я использую сервер Gevent WSGI:

 http_server = WSGIServer(('0.0.0.0', 5000), app).serve_forever()

И я выполнение запросов из шаблона, уже возвращенного по маршруту Flask.

Как можно выполнять параллельные запросы к API, не зацикливаясь на этом?

Ответы [ 2 ]

0 голосов
/ 08 марта 2020

Вы можете проверить, выполнив следующие действия:

  1. убедитесь, что ваш код monkey patched в самой первой строке (в противном случае, если какой-то модуль не пропатчен и выполняется какая-либо операция ввода-вывода вашего приложения) будет блокировать. Я помню, есть API в Gevent может проверить monkey.is_module_patched('request'));
  2. убедитесь, что вы не выполняете какую-либо задачу, связанную с ЦП (код, ограниченный ЦП, блокирует ваш код);

Надеюсь, это поможет!

0 голосов
/ 14 февраля 2020

Я никогда не использовал gevent, но если я правильно понимаю, у него есть однопоточное событие l oop (как asyncio). Но моё понимание может быть неправильным.

Посмотрите на этот ответ { ссылка }

Когда у вас есть фрагмент кода python, который принимает долгое время работы (в течение нескольких секунд), не вызывающее переключения гринлетов, все остальные задания greenlets / gevent будут «голодать» и не будут иметь времени вычислений, и это будет выглядеть как «зависание» вашего приложения.

Я предлагаю выполнить одно из следующих действий:

  • Либо запустите ваше веб-приложение на многопоточном WSGI-сервере
  • Или выясните, есть ли у gevent сетевой клиент, который вы можете использовать вместо этого из requests, основанного на greelets
  • Или, запустите блокирующую часть вашего кода в поточном инструменте
  • Или, вызовите from gevent import monkey; monkey.patch_all() как самое первое в вашем коде сервера, и посмотреть, если это делает requests вести себя неблокирующим.
...