Мне это надо для обновления базы, раз в месяц с одной конторы приходят обновления в виде sql файлов. Один из них более 130м. Файлы приплывают в архиве через форму, который распаковывается на сервере. Увы у хостинга есть ограничения на время ожидания (nginx), после которого иногда получается ошибка. ДА и логичнее всего, дождаться заливки файла на хост, и запустить процесс обновления в фоном режиме, а при обновлении странички показывать лог этого процесса. Было удобно, добавить флаг, не ожидать ответа. А просто запустить процесс в свободное плавание.
я бы сделал так: 1. есть форма, у которой обработчик -- парсер. через форму на сервер просто грузится файл и записывается в определённое место (возможно происходит его распаковка) 2. есть sh-скрипт, запускаемый по cron, проверяющий наличие файла, и если файл есть -- делающий его распаковку и выполнение, записывая результат в log-файл и удаляя исходный файл после завершения работы.
при отображении формы (шаг 1) там-же показывается результат последнего выполнения загрузки (log).
собственно sh-скрипт может реагировать не на само наличие файла с данными, а на какой-нить flag-файл (чтобы не хранить несколько последних версий данных и иметь возможность повторно загрузить их не ожидая заливки файла браузером на сервер)
Есть сайт на парсере, к нему надо прикрутить запуск и остановку приложения, чтобы не давать терминальный доступ. Остановку сделал через вызов taskkill, работает, т.к. программа выгружается после вызова. Остается только запуск.
Есть в парсере способ запустить скрипт/приложение и не дожидаться окончания его работы?
Это я описал в первом посте, не подходит. Нужен запуск и продолжение работы парсерного скрипта, не дожидаясь, когда запущенное приложение закончит работу.
Идея с кроном была, но как-то не гуд она. Ставить раз в минуту проверку появления файла, делать лок при запуске обновления, куда-то отправлять отчет об успешом/не успешном выполнении + время реакции. Люди они такие, тыркнули на кнопочку и хотят получить результат).
Но! В таком варианте оба файла логов будут перезаписываться каждый раз при запуске скрипта. Есле нужно дописывать файлы, т.е. вести нормальный лог, то:
Я знаю разницу между >> и > +). Я просто путаюсь в этих магических конструкциях 2>&1, вроде постепенно начал доходить их смысл. Меня интересует один общий лог файл, его так проще клиенту выводить. Второй раз они не запустят апдейт, у меня реализован лок
У нас например стоят лимиты CPU и памяти на cgi скрипты, поэтому ничего сверхобъемного cgi скрипт (или запущенный им процесс) все равно сделать не сможет. На скрипты, запускаемые из cron лимиты тоже есть, но гораздо более либеральные. Так что и от настроек окружения многое зависит.
Ничего необычного - обычная асинхронная обработка...
Да и пользователь вполне спокойно подождет, если вы ему напишете, что задача поставлена в очередь и результат будет через несколько минут (часов, дней :). Задачи можно складывать в базу, хороший алгоритм описан в статье Якова Сироткина -
У него пример для Оракла, но я похожий алгоритм использовал для работы с Кошельком Киви: счета хранил в таблице MySQL, а при поиске счетов для проверки использовал синтаксис .
вы работаете с ограниченными ресурсами. делаете заведомо долгую работу. в этом случае запросто можете не вписаться в имеющиеся ресурсы (процессорное время, память и timeout браузера).
например вчера сервер был не нагружен, поэтому sql скрит загрузился на 2.5 мин, и браузер дождался ответа.
сегодня сервер был загружен и загрузка данных происходила 3.5 мин и браузер отвалился по таймауту.
пользователь от таких неопределённостей ни фига не счастлив (нет ничего хуже, когда система то работает, то -- нет). к тому-же ему придётся повторно качать на сервер большой файл (а каналы бывают несимметричные + медленные, т.е. upload больших файлов может быть не в радость).
если подумать заранее и сразу сделать как следует, то как раз пользователь страдать не будет.
например: файл загрузился, вы его записали, поставили нужные флаги для cron-а и пользователю в окошке написали, что обработка начнётся через 3 мин. 40 сек (вам известно когда запускается скрипт обработки из крона, т.е. можете посчитать). заодно браузеру отдали указание сделать refresh через эти самые 3:40 пройдёт это время -- браузер сам обновит страницу и пользователь увидит сообщение, что данные загружаются (или распаковываются, ведь вы из sh-скрипта тоже можете выставлять флаги текущего состояния). очередной авто-рефреш через 30 сек -- и довольный пользователь видит или "данные загружаются" или "данные успешно загружены".
при этом и серверные ресурсы вы сберегли: не создавали один долгий процесс, потребляющий много памяти который мог-бы и не вписаться в лимиты), который должен был сначала получить многомегабайтный файл от пользователя (в память), потом сохранить, потом выполнить пару долгих внешних скриптов (распаковка + загрузка данных).
Логика крона и разделения мне понятно изначально...
я как раз таки и хочу разгрузить время выполнения и запустить скрипт апдейта в отдельном потоке. Мне не понятно почему, парсер не может запустить запустить процесс и забыть о нем, не дожидаясь пока он будет выполнен. Единственный плюс крона - возможно другие переменные окружения и лимиты на выполнение. Если же таковых лимитов нет, я подозреваю у меня что в кроне, что процесс запущенный из cgi окружения выполняются с одинаковыми лимитами и приоритетами. То почему я не могу запустить такой процесс из парсера напрямую? Я изначально заложил моменты, ожидания выполнения скрипта на сервере с выводом текущей обстановки в лог файл.
... что вполне логично и правильно. Если необходимо иное поведение, то это делается на уровне ОС через внешние программы, о чем в этой ветке подробно писали.
p.s. Тот способ, который вы упорно хотите использовать, конечно, имеет право на жизнь, но для выполнения асинхронных задач есть более простые и надежные способы.
Уже читал, но это извратный способ, да и работать должен при нахождении в системе, а запуск в моем случае будет вне профиля, пример из подобных тем не сработал.