Имеется страница, на которой пользователь вводит число и запускается цикл на это число итераций. Внутри цикла происходит отправка запросов на внешний сервер через Http фасад. Проблема в том, что на большом количестве итераций страница вскоре отваливается с ошибкой 499 Client Closed Request. Уже узнал что она означает, вопрос: как можно этого избежать? Пробовал вариант с созданием джоба, получилось, но когда пришло время настраивать супервизор, в поддержке хостинга сказали, что это возможно только на vps, а это для меня не вариант по финансам. При этом даже если и уходит в ошибку, цикл корректно выполняется до конца, все нормально. В беседе тематической спрашивал, посоветовали клиенту (т.е. мне) что-то отправлять, чтобы без ответа не сидеть и не провоцировать ошибку. Но толком и не понял что конкретно имеют ввиду. Кто-нибудь знает? p.s. отлавливать ошибку невозможно, т.к. это не исключение и не ошибка от сервера, сервер наоборот каждую итерацию цикла корректно отрабатывает. p.p.s. цитирую ответ поддержки хостинга: "Данную проблему необходимо решать на стороне клиента, нужно увеличивать время соединения со стороны клиента.".
Можно между итерациями по 30-50кб пробелов выкидывать в вывод в скрытых div-ах, после делать flush(), но это то ещё извращение и не гарантирует устойчивого соединения. На хостинге cron'ом можете php-скрипт пускать с бесконечным временем жизни?
Над кроном думал, я его для другого типа заданий использую. А здесь мне нужно немедленно приступить к выполнению
Создаётся "демон", скрипт по крону раз в минуту (чаще, вроде, нельзя) запускается, проверяет наличие какого-нить файла, когда нужно запустить тяжёлый долгий процесс, создаёте этот файл, демон пишет прогресс выполнения в файл, бд или куда ещё отправляет.
главное чтобы "Betruger" успел выполнить поставленную задачу за 55 секунд. --- Добавлено --- Иначе lock триггеры нужны.
не, там либа, чтобы лок создавать (код в репе умеет только лок в файлухе создавать, можно свой класс написать для других хранилищ лока). а из демона в цикле апить лок надо, если первый демон долго лок не апил, следующий демон его может порушить и начать работать, а в первом демоне при попытке апнуть потерянный лок исключение вылетит, я там README.md чутка подшаманил, комментов добавил
Мой вариант, когда крон дергает скрипт раз в минуту, чтобы не было казусов PHP: $exists = file_exists ( CRON_LOCK ); $resourse = fopen ( CRON_LOCK, 'w' ); if ( ! flock ( $resourse, LOCK_EX | LOCK_NB ) ) { exit; } /* ... */ if ( $exists ) { if ( file_exists ( CRON_MESSAGE_LOCK ) ) { exit; } // send message err file_put_contents ( CRON_MESSAGE_LOCK, null ); exit; } register_shutdown_function ( static function ( string $dir ) use ( $resourse ) { flock ( $resourse, LOCK_UN ); if ( is_null ( error_get_last () ) ) { unlink ( $dir . DIRECTORY_SEPARATOR . CRON_LOCK ); } }, __DIR__ ); // code... --- Добавлено --- всегда путаю resourse resourсe, где правильно, а где нет.
Господа, крон не вариант, еще раз, надо немедленно начать выполнение. Даже минута ожидания слишком много
Не совсем понял вопроса. В этих запросах я не жду ответа, я их просто отправляю. Сервер их обрабатывает сразу же, здесь никаких проблем нет. Клиент (т.е. пользователь, запустивший у меня цикл), ждет его окончания. После цикла у меня return на эту же страницу с flash-сообщением
всмысле ?? А зачем клиенту ждать то ? можно так: В личном кабинете отправил запрос и ему в ответ светится "ваш запрос в обработке" а ajax чекает php, который обращается к БД и смотрит. Статус запроса завершен или нет ? Далее при успехе, этому аяксу прилетает url для редиректа и шлем юзера куда подальше нужно.
Ещё раз, можно на хостинге по крону пускать скрипт без ограничения времени? что-то мешает из него чекать файл раз в секунду на предмет старта основного процесса?
https://habr.com/ru/post/179399/ --- Добавлено --- Мой бот на пхп жил 9 часов и умер в среде Win OS, необъяснив почему тварь сдохла.
логгируй каждый пердок, если торчит выяснить причину. на боевых писался вочер-магистр, что стартовал недостающие [пля, не преследнут ли за разглашение ))))))))))))]
Благодарю всех за участие в обсуждении, кажется, решил проблему. Переделал метод на бэке не на цикл, а на единичное выполнение операции, а цикл запихнул в ajax. Неактуально