Самый элегантный способ выполнения операций с процессором в приложении asyncio? - PullRequest
0 голосов
/ 25 октября 2019

Я пытаюсь разработать часть системы, которая имеет следующее требование:

  1. отправка состояния работоспособности на удаленный сервер (каждые X секунд)
  2. получение запроса на выполнение / отменуЗадания, связанные с процессором (например, - клонировать git repo, скомпилировать (используя conan) it .. etc).

Я использую socketio.AsyncClient для выполнения этих требований.

class CompileJobHandler(socketio.AsyncClientNamespace):
    def __init__(self, namespace_val):
        super().__init__(namespace_val)
        // some init variables

    async def _clone_git_repo(self, git_repo: str):
        // clone repo and return its instance
        return repo

    async def on_availability_check(self, data):
         // the health status
         await self.emit('availability_check', " all good ")

    async def on_cancel_job(self, data):
         // cancel the current job

    def _reset_job(self):
       // reset job logics

    def _reset_to_specific_commit(self, repo: git.Repo, commit_hash: str):
        // reset to specific commit

    def _compile(self, is_debug):
        // compile logics - might be CPU intensive

    async def on_execute_job(self, data):
        // **request to execute the job(compile in our case)**

        try:
            repo = self._clone_git_repo(job_details.git_repo)
            self._reset_to_specific_commit(repo, job_details.commit_hash)
            self._compile(job_details.is_debug)

            await self.emit('execute_job_response',
                            self._prepare_response("SUCCESS", "compile successfully"))

        except Exception as e:
            await self.emit('execute_job_response',
                            self._prepare_response(e.args[0], e.args[1]))

        finally:
            await self._reset_job()

Проблема со следующим кодом заключается в том, что при получении сообщения execute_job выполняется код блокировки, который блокирует всю систему async-io.

для решения этой проблемы я использовал ProcessPoolExecutor и цикл событий asyncio, как показано здесь: https://stackoverflow.com/questions/49978320/asyncio-run-in-executor-using-processpoolexecutor

после его использования функции клонирования / компиляции выполняются в другом процессе - так что почти достигаются мои цели.

вопросыУ меня есть:

  1. Как мне сделать код процесса более элегантным? (Сейчас у меня есть некоторые статические функции, и мне это не нравится ...)

Один из подходов - сохранить его какэто еще один способ - предварительно инициализировать объект (давайте назовем его CompileExecuter, создадим экземпляр этого типа и предварительно инициализируем его перед запуском процесса, а затем позволим процессу использовать его)

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

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

Другие подходы к выполнению этих требований приветствуются

...