Как мне сохранить состояние длительного процесса, вызываемого из Django?

StackOverflow https://stackoverflow.com/questions/853421

Вопрос

Я работаю над приложением Django, которое позволяет пользователю загружать файлы.Мне нужно выполнить некоторую обработку этих файлов на стороне сервера, прежде чем отправлять их на Амазонка S3.Прочитав ответы на этот вопрос и этот пост в блоге Я решил, что лучший способ справиться с этим — заставить мой обработчик представления вызывать метод Поджигатель удаленный объект для выполнения асинхронной обработки и последующего немедленного возврата Http 200 клиенту.У меня есть прототип, и он, кажется, работает хорошо, однако я также хотел бы сохранить состояние обработки, чтобы клиент мог опросить приложение, чтобы узнать, был ли файл обработан и загружен на S3.

Я могу легко справиться с опросом, но не уверен, где лучше всего хранить состояние процесса.Он должен быть доступен для записи процессу Pyro и доступен для чтения в моем опросе.

  • Я не решаюсь добавлять столбцы в базу данных для данных, которые на самом деле должны сохраняться только от 30 до 60 секунд.
  • Я рассмотрел возможность использования Django API низкоуровневого кэша и использование идентификатора файла в качестве ключа, однако я не верю, что это действительно то, для чего предназначена структура кэширования, и я не уверен, какие непредвиденные проблемы могут возникнуть при выборе этого пути.
  • Наконец, я рассмотрел сохранение состояния в объекте Pyro, выполняющем обработку, но тогда мне все равно кажется, что мне нужно будет добавить логический столбец базы данных «processing_complete», чтобы представление знало, запрашивать состояние из объекта Pyro или нет.

Конечно, существуют также некоторые проблемы с целостностью данных из-за отделения состояния от базы данных (что произойдет, если сервер выйдет из строя, а все эти данные будут находиться в памяти?).Мне предстоит услышать, как более опытные разработчики веб-приложений справятся с такого рода обработкой состояния.

Это было полезно?

Решение

Мы делаем это, имея в базе данных таблицу «Запрос».

Когда прибывает загрузка, мы создаем загруженный объект File и создаем запрос.

Запускаем фоновый пакетный процессор.

Мы возвращаем страницу 200 «мы работаем над этим» — на ней показаны запросы и их статус.

Наш пакетный процессор использует Django ORM.По завершении он обновляет объект Request.Мы можем (но не делаем этого) отправить уведомление по электронной почте.В основном мы просто обновляем статус, чтобы пользователь мог снова войти в систему и увидеть, что обработка завершена.


Примечания по архитектуре пакетного сервера.

Это сервер WSGI, который ожидает на порту запроса на пакетную обработку.Запрос представляет собой REST POST с идентификационным номером;пакетный процессор ищет это в базе данных и обрабатывает.

Сервер запускается автоматически через наш REST-интерфейс.Если он не запущен, мы создаем его.Из-за этого пользовательские транзакции кажутся медленными, ну да ладно.Он не должен развалиться.

Кроме того, у нас есть простой crontab, позволяющий проверить его работу.Больше всего, это будет в течение 30 минут между "Вы живы?" чекиУ нас нет формального сценария запуска (мы работаем под Apache с mod_wsgi), но мы можем создать сценарий «перезапуска», который обращается к файлу WSGI, а затем выполняет POST для URL-адреса, который проверяет работоспособность (и запускает пакетный процессор).

При запуске пакетного сервера могут быть необработанные запросы, для которых он никогда не получал POST.Итак, запуск по умолчанию — это вытягивание ВСЕЙ работы из очереди запросов — если, возможно, что-то пропущено.

Другие советы

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

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

AMQP создан именно для этого.Вместе с Сельдерей или Морковь и сервер брокера, например КроликMQ или НольMQ.

Это то, что мы используем в нашем последнем проекте, и оно отлично работает.

Для вашей проблемы Celery и RabbitMQ кажутся лучшими.RabbitMQ обеспечивает постоянство ваших сообщений, а Celery предоставляет простые представления для опроса, чтобы проверить состояние процессов, выполняемых параллельно.

Вас также может заинтересовать осьминог.

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

Если вам нужно что-то более мощное или более сложное, я бы посмотрел на что-то вроде Шестерен.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top