[PHP] Подскажите функцию
или спрашиваешь как твою долгую процедуру в отдельном потоке запустить, чтобы дать изначальному потоку подохнуть?
то есть ты спрашиваешь как flush сделать?Точнее, как сделать "окончательный" flush, чтобы клинет не ждал, не выведется ли там ещё чего-нибудь после этой длинной процедуры, и оборвал подключение к серверу.
или спрашиваешь как твою долгую процедуру в отдельном потоке запустить, чтобы дать изначальному потоку подохнутьНапример. Хотя, вроде бы, был какой-то способ просто сказать клиенту, что он должен отвалиться...
м.б. тут стоит ajax прикрутить?
Как запустить выполнение очень долгой процедуры, чтобы клиент отвалился, не дожидаясь её окончания? ajax - это те же яйца, только сбоку.
ЗЫ: На самом деле, клиентом будет другой php-скрипт
но на аджаксе я бы сделал дёргалку функции типа "готов_ли_ответ_на_мой_запрос" и если там "готово", брал бы ответ..
на то он и аджакс - для асинхронности
но на аджаксе я бы сделал дёргалку функции типа "готов_ли_ответ_на_мой_запрос"Замечательно. Сам-то запрос где начнёшь обрабатывать?
На всякий случай поясню - клиенту насрать, готов ли там ответ, ему вообще этот ответ не нужен. А эта ajax-овая примочка никак не поможет клиенту подать запрос так, чтобы он отвалился, не ожидая ответа.
пусть есть query.php, который формирует ответ на запрос.
при его запуске он генерит страницу типа (спасибо, ваш запрос обрабатывается).
при этом периодически чекается query_result_status.php. если там "ready", то запрашиваем get_query_result.php
связку хоть по PHPSESSID делай
пусть есть query.php, который формирует ответ на запрос.Повторю вопрос ещё раз. Где ты собрался на сервере запускать обработку самого запроса?
при его запуске он генерит страницу типа (спасибо, ваш запрос обрабатывается).
при этом периодически чекается query_result_status.php
<?php
echo "спасибо, ваш запрос обрабатывается"
?>
И где тут обработка запроса?
при этом периодически чекается query_result_status.phpДа насрать на статус.
Можно и не 1х1, в принципе пох
Проще всего так.
если запрос гетом, то во фрейм (или ифрейм) размером 1х1 соседний его яваскриптом передаешьТе же яйца, только сбоку.
Клиент не отваливается, но пользователь этого не увидит (если не посмотрит в строку состояния).
А в данном случае, клиент - не человекк, который сидит в браузере, а сервер, которому надо пнуть другой сервер, чтобы тот начал обрабатывать запрос. При этом, скрипт на первом сервере должен сказать "всё, запрос выполняется" и сдохнуть. Варианты вида "переписать скрипт на первом сервере, чтобы он висел, но это не было заметно пользователю первого сервера" не подходят, вопрос в том, что надо написать на втором сервере, чтобы первый понял, что ждать нечего.
Да, первый сервер, конечно, не будет лезть на второй через какие-то там сокеты, всё цивильно, через curl в худшем случае.
я так понял, ты хочешь, чтобы клиент стартовал задачу на сервере, а затем задача вела себя так, будто она независима? А ты не можешь экзекнуть стороннее приложение с этой задачей и спокойно завершить формирование страницы?
А ты не можешь экзекнуть стороннее приложение с этой задачейМогу, конечно.
Но вроде был какой-то цивильный способ решения такой проблемы, что-то типа client_abort.
можно сделать так: раз в минуту запускается скрипт, который проверяет наличие в каком-то файле единички, если она есть - запускается большая_и_толстая_функция. вот первый сервер дергает какой-то скрипт, который в файл кладет единичку (единичку можно заменить параметрами и т.д.)
можно сделать так: раз в минуту запускается скрипт, который проверяет наличие в каком-то файле единички, если она есть - запускается большая_и_толстая_функцияМолодец, изобрёл велосипед.
Крон - тоже не вариант (тем более, что второй сервер - не наш, и никто нас к крону не пустит хочется всё сделать наиболее красиво.
ну если не страшно, что одновременно будут работать несколько больших_и_толстых_функций
ну если не страшно, что одновременно будут работать несколько больших_и_толстых_функцийНу ты подумай ещё, может, и мьютексы изобретёшь
ну ты тоже подумай тогда
Прочитай ещё раз мой первый пост. Там вопрос поставлен предельно точно
Например. Хотя, вроде бы, был какой-то способ просто сказать клиенту, что он должен отвалиться...я пхп не знаю
но имхо так сделать нельзя
скрипт должен завершить работу, этого ждет апач
а общаться с апачем из скрипта ты не можешь
попробуй register_shutdown_function
а общаться с апачем из скрипта ты не можешьА вот и могу.
Но нужно общее решение, хз, что там - мб нгинкс какой-нибудь или иис.
Не катит:
<?php
function test {
echo 'test'.PHP_EOL;
}
register_shutdown_function('test');
?>
выдаёт "test", а не должно выдавать ничего.
А если клиента редиректить куда еще, отдавая ему подходящий заголовок с помощью вызова header ? Клиент уйдет на страничку "ваша заявка принята", а скрипт продолжит выполнение. (Я PHP не знаю, поэтому возможно совет фиговый.)
А если клиента редиректить куда еще, отдавая ему подходящий заголовок с помощью вызова header ?О, хороший вариант, кстати.
Вообще, по идее, header('Location: ...') где-то внутри делает как раз такую хрень, которая мне нужна... а можно ли это как-нибудь получить без использования header?
О, хороший вариант, кстатиа при этом разве не прекращается выполнение скрипта?
Зависит от настроек php, можно сделать, чтобы не прекращалось.
А вообще мой труЪ-вариант таков:
<?php
echo 'Your request has been accepted';
echo 'Можете уже закрыть браузер нахрен';
some_long_processing_that_can+take_up_to_several_hours_or_days;
?>
Какой нахуй хедер? Он не пошлётся, если в браузер уже начат выводдык вывода и не будет
хедер сразу на статическую страницу с текстом "подождите"
Какой нахуй хедер? Он не пошлётся, если в браузер уже начат вывод.Ясный пень не пошлется, так не надо ничего выводить клиенту, послать редирект и все.
Какой нахуй хедер? Он не пошлётся, если в браузер уже начат выводпрекрасно он пошлется
Попробуй
1
<?php
header('Location:http://forum.b.gz.ru')
?>
Я бы предложил запускать скрипт с помощью system, открепляя его от родительского процесса.
1X-Powered-By: PHP/5.2.0
header('Location//forum.b.gz.ru')
?>
Content-type: text/html
1
Warning: Cannot modify header information - headers already sent by (output started at PHPDocument1:2) in PHPDocument1 on line 3
echo 'Your request has been accepted';Ага, а на первом сервере - мегаинтеллектуальный курл, который поймёт, что можно уже прибить коннект нахрен и передать управление тому, что дальше.
echo 'Можете уже закрыть браузер нахрен';
а меня прекрасно перенаправил из браузера
ПопробуйУ тебя просто кэширование включено.
причем тут кеширование?
Тебе сказано уже - нельзя прибивать коннект. Так что неважно, что там на другом конце.
Он просто имеет в виду буферизацию вывода. С ней весь вывод хранится в буфере до момента окончания работы скрипта, или до ob_flush.
При том, что у тебя эта единичка в буфере лежит, и не отправляется клиенту.
Тебе сказано уже - нельзя прибивать коннектКем сказано?
Ради интереса поставь перед хедером слип в 5 секунд и посмотри, выведется ли твоя единичка. Спорю на пиво, что не выведется.
да, точно. Добавил ob_flush - браузер сказал "already sent"
Ладно, пенартур, пожалею я тебя.
А, так в этом случае браузер отконнектится от сервера, и скрипт ляжет.дык пенартур говорит что есть настройка пхп что скрипт не ляжет
Вопрос в том, как заставить клиента отвалиться.
Вот тут миллион решений. Если клиентом будет другой PHP-скрипт, то он тупо может анализировать выходной поток и при получении строки "Идите нахуй, пожалуйста" закрывать соединение. Что сложного-то?
Если клиентом будет другой PHP-скрипт, то он тупо может анализировать выходной поток и при получении строки "Идите нахуй, пожалуйста" закрывать соединениеАга, и при этом переписывать всё под сокеты?
curl_exec, он тебе по частям ответ выдавать не будет.
Кто тебе мешает заголовком ему отправить заранее определённый content_length?
О, спасибо - грязный хак, но работает.
<?php
header('Content-Length: 2');
echo 'abcdefg';
flush;
sleep(20);
file_put_contents('test.txt','test3.txt');
?>
Браузер двадцать секунд грузит, после чего выдаёт "ab"...
Ты не браузером проверяй, а curl'ом. Браузер в любом случае ждёт обрыва соединения, поэтому для него можно поиграться с content_type, в частности, попробовать указать ему, что он получает поток.
Да, кстати, проверь ещё оперой, потому что возможен такой вариант, что браузер тупо не начинает отрисовку страницы до тех пор, пока не получит разрыв соединения, поэтому рисует твои "ab" только по таймауту.
curl ждёт и выдаёт первые два символа.
Значит делай как я сказал: запускай "system'ом" процесс и отвязывай его от родительского.
ЗЫ: curl с CURL_FOLLOWLOCATION при использовании header:location точно так же тупит, хотя совершенно непонятно, какого хрена - уже и заголовки ему все отдали, и flush текста сделали, а он всё равно завершения работы скрипта ждёт, прежде чем по header: location перейти
Окей, способ интересней: делаешь pcntl_fork, смотришь, какой результат возвратила функция, и если 0 - то запускаешь длинный процесс (значит ты форкнутый щаз если не ноль - то тупо заканчиваешь себя.
Бля. У тебя PHP модулем к апачу? Тогда не прокатит.
Бля. У тебя PHP модулем к апачу?У меня на том сервере может быть абсолютно всё, что угодно. Известно только, что та мбудет php.
Похоже, придётся ждать завершения работы того скрипта, а это ещё некоторое количество геморроя - за транзакциями следить, таймаут корректно обрабатывать...
Тогда делай PHP CGI-приложением и форкайся. Форкнутый процесс отвязан от стандартного ввода апача, поэтому апач закроет коннект при завершении родительского приложения, а дочернее будет работать.
Тогда делай PHP CGI-приложениемПовторю ещё раз - там php может быть чем угодно. Требовать, чтобы там он был cgi-приложением - слишком геморройно, легче уж ответа ждать.
А-а-а, я просто тебя понял в том смысле, что ты на тот сервер что угодно можешь поставить.
А на этом сервере хочется использовать уже существующие прослойки, а не лезть напрямую в сокеты.
А у меня вот такая идея возникла. Что если передать браузеру хедер с редиректом и сказать, что соединение keep alive, а не close. По идее он тогда должен начать отоброжение сразу, а не ждать закрытия соединения. И получив header должен сразу средиректиться. Хотя может я и ошибаюсь - пробовать в лом.
Хотя не, посмотрел щас - почти все сервера и так keep alive говорят
А register_shutdown_function тебе не поможет?
А прочитать тред ты не можешь?
Оставить комментарий
kruzer25
К скрипту приходит запрос. Надо сказать клиенту, что запрос обрабатывается, и продолжить обработку (которая может быть очень долгой чтобы клиент при этом больше не ждал ответа.Что должно стоять на месте "?", чтобы клиент сразу решил, что не надо ждать ответа, что весь ответ уже получен?