Хранение состояния задачи между несколькими процессами Django - PullRequest
0 голосов
/ 14 июня 2010

Я строю мост для ведения журнала между сообщениями rabbitmq и приложением Django для сохранения состояния фоновой задачи в базе данных для дальнейшего исследования / просмотра, а также для возможности повторной публикации задач через интерфейс администратора Django.Полагаю, в этом нет ничего необычного, просто стандартный шаблон Producer-Consumer.

  1. Веб-приложение публикует в очередь сообщений и вставляет начальное состояние задачи в базу данных
  2. Consumer, которая является отдельным питоном.process, обрабатывает сообщение и обновляет состояние задачи в зависимости от вывода задачи

Проблема в том, что некоторые задачи отсутствуют в БД и поэтому никогда не выполняются.Я подозреваю, что это потому, что Потребитель получает сообщение раньше, чем выполняется фиксация БД.Таким образом, возвращение из Model.save () не означает, что транзакция завершилась и вся связь оборвалась.

Можно ли как-нибудь это исправить?Может быть, какой-нибудь сигнал post_transaction я мог бы использовать?

Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 14 июня 2010

Веб-приложение публикует в очередь сообщений и вставляет исходное состояние задачи в базу данных

Не делайте этого.

Веб-приложение публикует в очередь.Готово.Представьте результаты через шаблон и завершите веб-транзакцию.

Потребитель выбирает из очереди и делает что-то.Например, он может добавить журнал в базу данных для представления пользователю.Потребитель также может публиковать дополнительный статус в базе данных, когда он выполняет задачи.

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

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

0 голосов
/ 14 июня 2010

Это звучит хрупко для меня: у вас есть веб-приложение, которое отправляет сообщения в очередь, а , а затем вставляет начальное состояние в базу данных.Что произойдет, если пользователь обработает сообщение до того, как веб-приложение сможет зафиксировать начальное состояние?

Что произойдет, если веб-приложение попытается вставить новое состояние, когда БД заблокирована потребителем?

Чтобы исправить это, веб-приложение должно добавить начальное состояние к сообщению , и потребитель должен быть единственным, кто когда-либо записывал в БД.

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

[EDIT2] Некоторые идеи:

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

Почему веб-приложение не может видеть отложенные задачи, которые пользователь имеет в очереди?Может быть, у вас должно быть двух потребителей.Первый потребитель просто добавляет задачу в БД, фиксирует, а затем отправляет сообщение второму потребителю только с первичным ключом новой строки.Администратор iface может прочитать таблицу, пока второй потребитель пишет в нее.

Последняя идея: передайте транзакцию перед постановкой сообщения в очередь.Для этого вам просто нужно отправить «commit» в базу данных.Это будет выглядеть странно (и я, конечно, не рекомендую это для любого случая), но здесь, возможно, имеет смысл зафиксировать новую строку вручную (то есть, прежде чем вы вернетесь к своей среде, которая обрабатывает обычную логику транзакций).

...