Как хранить состояние для продолжительного процесса, вызванного из Django? - PullRequest
5 голосов
/ 12 мая 2009

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

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

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

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

Ответы [ 3 ]

6 голосов
/ 12 мая 2009

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

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

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

Мы возвращаем страницу 200 "мы работаем над этим" - она ​​показывает запросы и их статус.

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


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

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

Сервер автоматически запускается нашим интерфейсом REST. Если это не работает, мы порождаем это. Это делает пользовательскую транзакцию медленной, ну да ладно. Это не должно разбиться.

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

Когда запускается пакетный сервер, могут быть необработанные запросы, для которых он никогда не получал POST. Таким образом, запуск по умолчанию - вывести ВСЕ работы из очереди запросов - при условии, что она что-то пропустила.

5 голосов
/ 14 декабря 2009

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

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

AMQP создан именно для этого. Вместе с Сельдереем или Морковь и брокерским сервером, таким как RabbitMQ или ZeroMQ .

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

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

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

1 голос
/ 12 мая 2009

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

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

...