Лучший способ обработки запускаемой пользователем задачи (например, импорта данных) в Django - PullRequest
0 голосов
/ 26 марта 2020

Мне нужно ваше мнение о вызове, с которым я сталкиваюсь. Я создаю веб-сайт, который использует Django в качестве бэкэнда, PostgreSQL в качестве моей БД, GraphQL в качестве моего уровня API и React в качестве моей инфраструктуры веб-интерфейса. Сайт размещен на Heroku. Я написал сценарий python, который регистрирует меня в моей учетной записи Gmail, анализирует несколько писем на основе заранее определенных условий и сохраняет проанализированные данные в Google Sheet. Теперь я хочу, чтобы скрипт был частью моего веб-сайта, на котором пользователь будет указывать, что именно нужно анализировать (например, фильтры), а затем отображать проанализированные данные в таблице для проверки точности задачи анализа.

Часть, с которой мне нужна помощь, - это то, как спроектировать такой рабочий процесс. Ниже приведено несколько идей, которые мне удалось выработать после некоторого поиска в Google:

  1. генерирует мутацию graphQL, которая сохраняет «задачу» в модели задач. После сохранения новой записи задачи сценарий запускается Django. Пока не уверен, может ли Signal запускать пользовательские функции python, но из того, что я прочитал, это кажется выполнимым.
  2. Используйте Celery для асинхронного запуска этой задачи. Но я не уверен, что асинхронные задачи - это то, что мне нужно, потому что мне нужно, чтобы эта задача запускалась сразу после того, как пользователь запустил функцию из внешнего интерфейса. Но я могу ошибаться здесь. Я также не уверен, нужен ли мне Redis для хранения сведений о задаче, или я могу сделать это на PostgreSQL.

Каков наилучший способ реализации этой функции? Задачей может быть что угодно, не обязательно парсинг писем; это также может быть импорт данных из Excel. Любая задача, созданная пользователем, а не запланированная или повторная задача.

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

Будем рады учиться на вашем опыте.

1 Ответ

1 голос
/ 27 марта 2020

Вы можете разбить вашу проблему на следующие шаги:

  1. Пользователь указывает параметры задачи
  2. Система выполняет задачу
  3. Система отображает результат для пользователя

Вы можете сделать все это:

  1. Последовательно и синхронно одним махом; или
  2. Шаг за шагом, асинхронно.

Синхронно

Вы можете запустить скрипт при генерации ответа, но он будет иметь следующие недостатки:

  1. Процесс на сервере, обрабатывающий ваш запрос, будет заблокирован до завершения сценария. Это может повлиять или не повлиять на обработку других запросов тем же сервером (это будет зависеть от количества одновременных запросов, обрабатываемых скриптом и т. Д. c.)
  2. Клиент (например, ваш браузер) и даже сервер может отключиться, если выполнение сценария занимает слишком много времени. Вы можете исправить это до некоторой степени, настроив свой сервер соответствующим образом.

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

Нет настройки очереди сообщений, планировщика задач или чего-либо еще необходимого.

Асинхронно

В идеале, хотя для долгосрочных задач, лучше, чтобы это выполнялось вне обычного запроса-ответа l oop для следующих преимуществ:

  1. Сервер, отвечающий на запросы, может фактически обслуживать другие запросы.
  2. Некоторые сценарии могут занять некоторое время, некоторые вы даже не знаете, будет ли он завершен sh
  3. Сценарий больше не зависит от надежности сети (представьте, что запуск дорогое задание, тогда ваше inte rnet соединение пропускается или просто прерывисто; вы ничего не сможете сделать)

Недостатком этого является то, что вы должны настроить больше вещей, что увеличивает сложность проекта и точки отказа.

Производитель-потребитель

Что бы вы ни выбрали, обычно лучше следовать шаблону производитель-потребитель:

  1. Производитель создает задачи и помещает их в очередь
  2. Потребитель берет задачу из очереди и выполняет ее

Производитель в основном вы, пользователь. Вы указываете задачу и параметры этой задачи.

В этой очереди может быть любое хранилище данных: хранилище данных в памяти, например, Redis; очередь сообщений, такая как RabbitMQ; или система управления реляционной базой данных, такая как PostgreSQL.

Потребителем является ваш скрипт, выполняющий эти задачи. Существует несколько способов запуска потребителя / скрипта: через Celery, как вы упомянули, который запускает несколько рабочих для выполнения задач, проходящих через очередь; через простой, основанный на времени планировщик заданий, такой как crontab; или даже вы вручную запускаете скрипт

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

Но просто для того, чтобы дать вам более актуальное руководство:

Просто Сохраняйте это простым, если у вас нет веских причин для этого (например, отключение сервера или соединение inte rnet на практике ненадежно), на самом деле нет причин для фантазии.

Чем больше блокируется задача, или чем дольше она выполняется или чем больше она зависит от сторонних API через сеть, тем больше смысла использовать sh в фоновом процессе для повышения надежности и отказоустойчивость.

В вашем сценарии импорта электронной почты я, скорее всего, добавлю sh в фоновый режим:

  1. У вас будет страница, где вы можете добавить задачу в базу данных.
  2. На странице сведений о задаче отобразите сведения о задаче и приведенный ниже результат, если он существует, или «Обработка ...», в противном случае
  3. Иметь скрипт, который выполняет задачи (импортировать электронную почту из gmail с учетом параметров задачи) и сохранять результаты в базе данных
  4. Запланировать запуск этого скрипта каждые несколько минут через crontab

Да, у вышеизложенного есть побочные эффекты, такие как crontab, запускающий скрипт несколько раз в одно и то же время, и тому подобное, но я не буду go вдаваться в подробности, не зная больше о специфике задачи.

...