триггерная функция после возврата HttpResponse из представления django - PullRequest
6 голосов
/ 29 февраля 2012

Я разрабатываю веб-сервер django, на котором другая машина (с известным IP-адресом) может загрузить электронную таблицу на мой веб-сервер. После того, как электронная таблица была обновлена, я хочу запустить некоторую обработку / проверку / анализ в электронной таблице (которая может занять> 5 минут - слишком долго, чтобы другой сервер разумно ожидал ответа), изатем отправьте другой машине (с известным IP) HttpResponse, указывающий, что обработка данных завершена.

Я понимаю, что вы не можете сделать processing.data() после возврата HttpResponse, но функционально я хочу кодэто выглядит примерно так:

# processing.py
def spreadsheet(*args, **kwargs):
    print "[robot voice] processing spreadsheet........."
    views.finished_processing_spreadsheet()

# views.py
def upload_spreadsheet(request):
    print "save the spreadsheet somewhere"
    return HttpResponse("started processing spreadsheet")
    processing.data()

def finished_processing_spreadsheet():
    print "send good news to other server (with known IP)"

Я знаю, как написать каждую функцию в отдельности, но как мне эффективно вызвать processing.data() после того, как views.upload_spreadsheet вернул ответ?

Я пытался использовать сигнальную платформу request_finished django , но это не вызывает метод processing.spreadsheet() после возврата HttpResponse.Я попытался использовать декоратор на views.upload_spreadsheet с той же проблемой.

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

Спасибо за вашу помощь!

Ответы [ 2 ]

4 голосов
/ 29 февраля 2012

На самом деле у Джанго есть синхронная модель.Если вы хотите выполнить настоящую асинхронную обработку, вам нужна очередь сообщений.В django чаще всего используется сельдерей, он может показаться немного «излишним», но это хороший ответ.

Зачем нам это нужно?потому что в приложении wsgi apache передает запрос исполняемому файлу, а исполняемый файл возвращает текст.Apache подтверждает окончание запроса только один раз, когда исполняемый файл заканчивает выполнение.

3 голосов
/ 29 февраля 2012

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

Вам следует использовать очередь фоновых задач , в основном имеет 2 процесса: ваш сервер и диспетчер фоновых задач .Сервер должен делегировать обработку электронной таблицы диспетчеру фоновых задач .Когда фоновое задание выполнено, оно должно как-то сообщить об этом серверу.Например, он может сделать model_with_spreadsheet.processed = datetime.datetime.now ().

Вы должны использовать менеджер фоновых заданий наподобие django-ztask (очень простоsetup), сельдерей (очень мощный, в вашем случае, вероятно, избыточный) или даже спулер uwsgi (который, очевидно, требует развертывания uwsgi).

...