Python ProcessPoolExecutor не может обработать исключение - PullRequest
0 голосов
/ 04 августа 2020

Я запускаю сервер Tornado с ProcessPoolExecutor для параллельной обработки нескольких запросов. Проблема в том, что в одном конкретном случае, когда в одном из процессов возникает исключение, оно не распространяется, а вместо этого происходит сбой процесса с этой ошибкой:

concurrent.futures.process._RemoteTraceback:
\n'''\nTraceback (most recent call last):
\n  File \"C:\\Users\\ActionICT\\anaconda3\\lib\\concurrent\\futures\\process.py\", line 367, in _queue_management_worker\n    result_item = result_reader.recv()
\n  File \"C:\\Users\\ActionICT\\anaconda3\\lib\\multiprocessing\\connection.py\", line 251, in recv
\n    return _ForkingPickler.loads(buf.getbuffer())\nTypeError: __init__() missing 1 required positional argument: 'is_local'\n'''\n\nThe above exception was the direct cause of the following exception:
\n
\nTraceback (most recent call last):\n  File \"C:\\S1\\Product\\Baseline\\PYTHON\\lab\\controller.py\", line 558, in get\n    output = exec_future.result()
\n  File \"C:\\Users\\ActionICT\\anaconda3\\lib\\concurrent\\futures\\_base.py\", line 428, in result\n    return self.__get_result()\n  File \"C:\\Users\\ActionICT\\anaconda3\\lib\\concurrent\\futures\\_base.py\", line 384, in __get_result
\n    raise self._exception\nconcurrent.futures.process.BrokenProcessPool: A process in the process pool was terminated abruptly while the future was running or pending.\n

Я пробовал это в отладчике , и обнаружил, что проблема заключается в выполнении этого

    def _send_bytes(self, buf):
        ov, err = _winapi.WriteFile(self._handle, buf, overlapped=True)
        try:
            if err == _winapi.ERROR_IO_PENDING:
                waitres = _winapi.WaitForMultipleObjects(
                    [ov.event], False, INFINITE)
                assert waitres == WAIT_OBJECT_0
        except:
            ov.cancel()
            raise
        finally:
            nwritten, err = ov.GetOverlappedResult(True)
        assert err == 0
        assert nwritten == len(buf)

Это вызывается, когда процесс пытается распространить исключение на соответствующий объект Future. В первой строке при вызове _winapi.WriteFile все вылетает в отладчике, и я не могу понять почему. Есть идеи?

1 Ответ

0 голосов
/ 04 августа 2020

Я нашел обходной путь: я заключил внутреннюю оболочку в отдельный процесс в try except, затем скопировал старое исключение в новое исключение и вызвал его. Не знаю почему ... но работает.

def _execute_tuning(tune_parameters: TuneParameters):
# function to parallelize  todo to be refactored

# execute scenario, then write result or error in output

try:
    config.generate_project_config(
        project_name=tune_parameters.project_name,
        scenario_name=tune_parameters.scenario_name
    )

    config.generate_session_log_config(project_name=tune_parameters.project_name,
                                                    scenario_name=tune_parameters.scenario_name)

    tree = DecisionTreeGenerator(tune_parameters.project_name, tune_parameters.scenario_name)

    tree.fit(
        # todo refactor
        auto_tune=True if tune_parameters == 'true' else False,
        max_depth=tune_parameters.max_depth,
        columns=tune_parameters.columns,
        min_samples_leaf=tune_parameters.min_samples_per_leaf,
        max_leaf_nodes=tune_parameters.max_leaf_nodes
    )

    kpi = KPICalculator(tune_parameters.project_name, tune_parameters.scenario_name)
    kpi.run(do_optimization_kpi=False)
except Exception as exc:
    Loggers.application.exception(exc)
    exc_final = Exception(str(exc))
    exc_final.__traceback__ = exc.__traceback__
    raise exc_final
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...