Flask: Как мне успешно использовать многопроцессорность (не многопоточность)?

Я использую сервер Flask для обработки запросов на некоторые задачи обработки изображений.

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

Я предпочитаю многопроцессорность, а не многопоточность (пожалуйста, предположите первое в ваших ответах).

Но многопроцессорность с opencv явно нарушена (у меня Python 2.7 + macOS): https://github.com/opencv/opencv/issues/5150

Одно решение (см. https://github.com/opencv/opencv/issues/5150#issuecomment-400727184) — использовать отличный Loky (https://github.com/tomMoral/loky)

[Вопрос: Какие еще рабочие решения существуют, кроме concurrent.futures, loky, joblib..?]

Но Loky приводит меня к следующей трассировке стека:

    a,b = f.result()
  File "/anaconda2/lib/python2.7/site-packages/loky/_base.py", line 433, in result
    return self.__get_result()
  File "/anaconda2/lib/python2.7/site-packages/loky/_base.py", line 381, in __get_result
    raise self._exception
BrokenProcessPool: A task has failed to un-serialize. Please ensure that the arguments of the function are all picklable.

This was caused directly by
'''
Traceback (most recent call last):
  File "/anaconda2/lib/python2.7/site-packages/loky/process_executor.py", line 391, in _process_worker
    call_item = call_queue.get(block=True, timeout=timeout)
  File "/anaconda2/lib/python2.7/multiprocessing/queues.py", line 135, in get
    res = self._recv()
  File "myfile.py", line 44, in <module>
    app.config['EXECUTOR_MAX_WORKERS'] = 5
  File "/anaconda2/lib/python2.7/site-packages/werkzeug/local.py", line 348, in __getattr__
    return getattr(self._get_current_object(), name)
  File "/anaconda2/lib/python2.7/site-packages/werkzeug/local.py", line 307, in _get_current_object
    return self.__local()
  File "/anaconda2/lib/python2.7/site-packages/flask/globals.py", line 52, in _find_app
    raise RuntimeError(_app_ctx_err_msg)
RuntimeError: Working outside of application context.

This typically means that you attempted to use functionality that needed
to interface with the current application object in some way. To solve
this, set up an application context with app.app_context().  See the
documentation for more information.
'''

Функции для распараллеливания вызываются не из app/main.py, а из произвольно глубокого подмодуля.

Я попробовал столь же полезный https://flask-executor.readthedocs.io/en/latest, тоже пока зря.

Итак, вопрос:

Как я могу безопасно передать контекст приложения рабочим процессам или иным образом заставить работать многопроцессорную обработку (не прибегая к многопоточности)?

Я могу построить этот вопрос, если вам нужна дополнительная информация. Как всегда большое спасибо.

Связанные ресурсы:

Копировать контекст запроса/приложения flask в другой процесс

Многопроцессорная обработка Flask

Обновление:

Вызовы, отличные от opencv, отлично работают с flask-executor (без Loky) :)

Проблема возникает при попытке вызвать функцию opencv, например knnMatch.

Если Loky решит проблему с opencv, интересно, можно ли заставить ее работать с flask-executor (пока не для меня).


person jtlz2    schedule 25.09.2019    source источник