Я записал сценарий Python для обработки некоторых данных из файлов CSV. Сценарий берет между 3 - 30 минутами для завершения, в зависимости от размера CSV.
Теперь я хочу вставить веб-интерфейс к этому, таким образом, я могу загрузить файлы данных CSV отовсюду. Я записал основному HTTP страницу загрузки POST и использовал модуль CGI Python - но сценарий просто испытывает таймаут через какое-то время.
Выходные HTTP-заголовки сценария в запуске и выходные биты данных после итерации по каждой строке CSV. Как пример, этот оператор печати инициировал бы каждые 30 секунд или около этого.
# at the very top, with the 'import's
print "Content-type: text/html\n\n Processing ... <br />"
# the really long loop.
for currentRecord in csvRecords:
count = count + 1
print "On line " + str(count) + " <br />"
Я предположил, что браузер будет получать заголовки и ожидать, так как он продолжает получать небольшие биты данных. Но то, что на самом деле, кажется, происходит, является этим, не получает данных вообще, и Error 504
испытывает таймаут при предоставлении CSV с большим количеством строк.
Возможно, существует некоторое кэширование, происходящее где-нибудь? От журналов,
[Wed Jan 20 16:59:09 2010] [error] [client ::1] Script timed out before returning headers: datacruncher.py, referer: http://localhost/index.htm
[Wed Jan 20 17:04:09 2010] [warn] [client ::1] Timeout waiting for output from CGI script /Library/WebServer/CGI-Executables/datacruncher.py, referer: http://localhost/index.htm
Что лучший способ состоит в том, чтобы разрешить это, или, разве не уместно запустить такие скрипты в браузере?
Править: Это - сценарий для моего собственного использования - я обычно намереваюсь использовать его на своем компьютере, но я думал, что веб-интерфейс мог пригодиться при перемещении, или например с телефона. Кроме того, нет действительно ничего для загрузки - сценарий по всей вероятности пошлет отчет по электронной почте прочь в конце.
Я бы предложил изменить метод, чтобы вернуть объект Result вместо параметра out. Объект результата может содержать исключение, а также значение arg.
-121--2871477- Вероятно, вам потребуется выполнить stdout.flush ()
, так как сценарий еще ничего не записывает на веб-сервер до тех пор, пока не будет записан объем данных буфера страницы, что не произойдет до истечения времени ожидания.
Но правильный способ решить эту проблему, как другие предлагали, состоит в том, чтобы выполнить обработку в отдельном потоке/процессе и показать пользователю автоматически обновляемую страницу, которая показывает состояние, с индикатором выполнения или каким-либо другим визуальным видом, чтобы предотвратить их скучание.
-121--3787407-Я бы разделил работу следующим образом:
URL-адрес веб-приложения, принимающего размещенный CSV-файл. Веб-приложение помещает CSV-содержимое в автономную очередь, например таблицу базы данных. Ответ веб-приложения должен быть уникальным идентификатором для поставленного в очередь предмета (например, используйте столбец автоприращения идентификатора). Клиент должен сохранить этот идентификатор для части 3.
Автономное служебное приложение, которое опрашивает очередь для работы и выполняет обработку. После завершения обработки сохраните результаты в другой таблице базы данных, используя уникальный идентификатор в качестве ключа.
URL-адрес веб-приложения, который может получать обработанные результаты, http ://server/getresults/uniqueid/
. Если обработка завершена (т.е. уникальный идентификатор найден в таблице базы данных результатов), то возвращайте результаты. Если ответ не завершен, он должен содержать код, указывающий на это. Например, пользовательский заголовок HTTP, ответ о состоянии HTTP, тело ответа 'PENDING' или подобное.
У меня здесь хорошо работают Dropbox, SVN и Xcode, у меня не было проблем с тем, что когда-либо.
Вам даже не нужно внимательно относиться к тому, с какой машины вы фиксируете или обновляете данные, поскольку Dropbox синхронизирует ВСЕ.
-121--1043812-Я думаю, что это потому, что Луа относительно прост и прагматичен. Он не пытается быть языком для создания следующей операционной системы, Crysis 3 или клона SAP, но то, что он делает, делает хорошо, то есть служит языком сценариев.
-121--933845-У меня была такая ситуация и я использовал cronjobs. Сценарий HTTP просто записывает в очередь выполняемое задание (БД или файл в каталоге), а cronjob считывает его и выполняет это задание.
Я бы предложил изменить метод, чтобы вернуть объект Result вместо параметра out. Объект результата может содержать исключение, а также значение arg.
-121--2871477- Вероятно, вам потребуется выполнить stdout.flush ()
, так как сценарий еще ничего не записывает на веб-сервер до тех пор, пока вы не запишете данные в буфер страницы, что не произойдет до истечения времени ожидания.
Но правильный способ решить эту проблему, как другие предлагали, состоит в том, чтобы выполнить обработку в отдельном потоке/процессе и показать пользователю автоматически обновляемую страницу, которая показывает состояние, с индикатором выполнения или каким-либо другим визуальным видом, чтобы предотвратить их скучание.
-121--3787407-См. Наблюдение за длительными процессами через CGI Рэндала Шварца. В статье используется Perl, но техника не зависит от языка.
ИМХО. Лучший способ - запустить независимый скрипт, который где-то обновляется (Flat File, база данных и т. Д.). Я не знаю, как вилить независимый процесс из Python, поэтому я не могу дать какие-либо примеры кода.
Чтобы показать прогресс на веб-сайте, реализуйте запрос AJAX на страницу, которая читает эти обновления состояния, и, например, показывает приятную панель прогресса.
Добавьте что-то вроде Settimeout («RefreshProgressbar [...]) или мета-обновление для автоматического освежения.
Я думаю, что это потому, что Луа относительно прост и прагматичен. Он не пытается быть языком для создания следующей операционной системы, Crysis 3 или клона SAP, но то, что он делает, делает хорошо, то есть служит языком сценариев.
-121--933845-Я бы предложил изменить метод, чтобы вернуть объект Result вместо параметра out. Объект результата может содержать исключение, а также значение arg.
-121--2871477- Вероятно, вам потребуется выполнить stdout.flush ()
, так как сценарий еще ничего не записывает на веб-сервер до тех пор, пока вы не запишете данные в буфер страницы, что не произойдет до истечения времени ожидания.
Но правильный способ решить эту проблему, как другие предлагали, состоит в том, чтобы выполнить обработку в отдельном потоке/процессе и показать пользователю автоматически обновляемую страницу, которая показывает состояние, с индикатором выполнения или каким-либо другим визуальным видом, чтобы предотвратить их скучание.
Очень похожий вопрос здесь. Я предлагаю отбросить длительный процесс и вернуть пользователю индикатор прогресса на основе ajax. Таким образом, у пользователя будет роскошь веб-интерфейса, а у вас - отсутствие тайм-аутов.