2012-02-29 1 views
6

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

Я понимаю, что вы не можете сделать 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 ответил (а) отзыв?

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

У меня есть подозрение, что это может иметь какое-то отношение к написанию middleware или, возможно, custom class-based view, ни один из которых не имеет опыта, поэтому я думал, что поставил бы вопрос во вселенную в поисках какой-то помощи.

Благодарим за помощь!

ответ

4

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

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

+0

Спасибо за объяснение, почему это необходимо, Кристоф. Основываясь на ваших и объяснениях jpic, я думаю, что я проведу сельдерей после того, как я получу немного больше сна. – dino

3

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

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

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

+0

Спасибо за быстрый ответ. Основываясь на ваших ответах и ​​christophe31, я думаю, что я проведу сельдерей после того, как я получу немного больше сна. – dino

+0

Закройте вопрос, пожалуйста, – jpic