Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > JavaScript: Общие вопросы > Фоновый процесс "синхронизации"


Автор: ksnk 16.10.2008, 17:12
Хочется каким-нибудь образом запустить фоновый процесс, который не торопясь прочитает 4-х метровый csv файл и распихает все добро по полочкам магазина. Написанный сейчас процесс разборки относительно быстро работал на небольших файлах, а вот обработка такого здорового занимает минуты 2-3. В течении этого времени, сервер совершенно недоступен, что, несколько некомфортно...

проблема в том, что на этом самом хосте закрыты функции запуска сторонних приложений
Цитата

disable_functions|    dl, shell_exec, exec, system, passthru, popen, proc_open, proc_nice, proc_get_status, proc_close, proc_terminate, posix_mkfifo, set_time_limit, chown, chgrp    dl, shell_exec, exec, system, passthru, popen, proc_open, proc_nice, proc_get_status, proc_close, proc_terminate, posix_mkfifo, set_time_limit, chown, chgrp


Safe mode не включен.

В принципе, наверное, есть возможность открыть нужные мне popen/pclose, пообщавшись с администрацией хостинга, но может быть есть и более другой способ запустить "фоновый" процесс на сервере?

Автор: ksnk 16.10.2008, 17:32
2 модератор... Sorry!  smile  запостил тему не в тот раздел... Можно переместить куда-нибудь в PHP?

Автор: Nigel 18.10.2008, 11:38
Файл у тебя маленький, как может сервак вешаться? Я подозреваю, ты просто explode'ишь данные и инсертишь в таблицу, при чем каждый раз создавая однотипные запросы в базу, которая к тому же MyISAM. Я прав?

Автор: ksnk 18.10.2008, 12:07
Nigel, Он маленький, но он csv, который приходится читать построчно. В каждой строке, в частности, имя картинки, которую надо еще поискать на сервере... Данные пихаются не в одну таблицу, а в три сложно повязанных между собой.  Оптимизоровать , конечно, есть куда, однако вопрос не в скорострельности обработчика, который должен выполняться не чаще раза в пару дней, а в том, как сделать эту обработку "незаметной".

Для проверки как можно подвесить сервер - можно потестировать исполнение долго исполняющегося скрипта на Денвере. Конфигурация Денвера несколько далека от "нормальных" хостеров, однако у моего хостера картина именно такая..

Автор: ksnk 18.10.2008, 17:23
Все мои беды от большого ума...  smile 
Как показали эксперименты, достаточно закрыть файл сессии и все "некомфортные" тормоза на сервере благополучно исчезли... Итого рецепт "фонового" процесса в моем случае 
  •  запуск функции экспорта базы товаров Ajax'ом. Через небольшой таймаут Ajax процесс тихонечко прибивается...
  •  в функции экспорта, перед длинной работой нужно сделать session_write_close
  •  длинная функция периодически выкладывает в базу репорт о работе, по содержанию репорта можно судить о прогрессе экспорта...
  •  Операции изменения базы товаров на время экспорта (при наличии репорта о выполнени операции) блокируются ...

Автор: sTa1kEr 18.10.2008, 20:22
Цитата(ksnk @  18.10.2008,  18:23 Найти цитируемый пост)
Через небольшой таймаут Ajax процесс тихонечко прибивается...

Не хорошо так делать. Лучше по хорошему вертуть ответ, что мол файл принять, обработка началаь и продолжить работу.

Цитата(ksnk @  18.10.2008,  18:23 Найти цитируемый пост)
в функции экспорта, перед длинной работой нужно сделать session_write_close

Не совсем понял. А в чем смысл?

Добавлено через 4 минуты и 42 секунды
А, ясно, что бы последующи запросы не блокировались.

Автор: ksnk 18.10.2008, 20:38
Цитата

Не хорошо так делать. Лучше по хорошему вертуть ответ,...

При моих настройках я не могу корректно закончить вывод. :-( Imho, он корректно заканчивает вывод только завершением скрипта...

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

Цитата

Не совсем понял. А в чем смысл? 

Смысл в том, что скрипт PHP, обычно, блокирует файл сессии, чтобы другие скрипты той-же сессии с ним не конфликтовали. Именно это и вызывает у меня на хостинге (и в Денвере, кстати), эффект "зависания" ответа сервера. Следующий скрипт честно ждет разблокировку сессии...

Автор: sTa1kEr 18.10.2008, 20:54
Цитата(ksnk @  18.10.2008,  21:38 Найти цитируемый пост)
При моих настройках я не могу корректно закончить вывод. :-( Imho, он корректно заканчивает вывод только завершением скрипта...

В общем случае возможно. Нужно просто самому передать заголовки "Connection: Close" и длину контента "Content-Length: xxx". Тогда апач, получив необходимый контент отправит ответ клиенту, а скрипт продлжит работу.

Автор: ksnk 18.10.2008, 21:40
sTa1kEr, Да, но апач при этом не закроет сетевой сокет, и некоторые броузеры будут продолжать считать, что соединение все еще идет. Будут крутить значками подгрузки и, возможно, не отдадут вывод ajax-скрипту в нужный момент... Какие - я уже не помню, но по моему FF2 этим страдал... 
Впрочем, результат, вроде,  получат все, нужно только с состоянием ajax'а поразбираться... 
Нужно будет попроверять, как нибудь потом smile

Автор: ksnk 25.10.2008, 09:59
В продолжении моей эпопеи с "синхронизацией"...

Как оказалось, на некоторых хостингах закрыта функция set_time_limit... (Причем, практически на всех! как я раньше не заметил?  smile ), так что к задаче оказалось необходимо таки по делу прикрутить Ajax.

Итого в дополнении к описанному алгориму:

в репорт включаем позицию строки, которую успели прочитать и время репорта. При выдаче  репорта он дополняется текущим временем на сервере. 

Чтобы не загромождать процессор ненужными обновлениями репортов, обновляем его каждые 100 строк. Читаем репорты тоже не часто, раз в 5-10 сек.

если получатель репортов обнаружил 2 подряд одинаковых репорта с большой разницей во времени - считаем, что процесс уже умер. Запускаем новый процесс командой "читай тот-же csv со строки XX". XX  из последнего репорта. по этой команде новая версия процесса обязана прочитать заголовок, попустить нужное количество строк и импортировать дальше...

P.S.
nested-sets - это зло...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)