LINUX.ORG.RU

[php] Реализация разрыва http соединения до окончания работы скрипта

 


0

1

Добрый день!
Есть скрипт, который принимает POST, проверяет данные и, если они валидны, на этом месте можно закрывать HTTP соединение с сообщением об успешном приёме данных (если не валидны, то тоже закрывать, но с сообщением об ошибке), после чего начать длительную и нудную обработку.

Используется Nginx и php-fpm. Как такое реализовать?
У меня пока только одна идея - написать ещё одного демона, который бы через shared memory (вроде пых умеет) продолжал обработку, но вообще, может быть, можно Nginx'у послать хитрую команду для закрытия HTTP-соединения?

★★

Последнее исправление: SaBo (всего исправлений: 1)

а для разных кодов возврата юзать 200 / 403 например.

isden ★★★★★
()
Ответ на: комментарий от Pinkbyte

а при terminate current script у тебя сеанс с юзером не закрывается? o_O


Мне надо сначала закрыть http-соединение (закрыть сеанс с юзером), затем продолжить выполнение скрипта и только после этого убить скрипт.

SaBo ★★
() автор топика
Ответ на: комментарий от SaBo

хз, хедер close по идее должен говорить клиенту что типа надо-бы и разорвать коннект.

HTTP/1.1 defines the «close» connection option for the sender to signal that the connection will be closed after completion of the response. For example,

Connection: close

in either the request or the response header fields indicates that the connection SHOULD NOT be considered `persistent' (section 8.1) after the current request/response is complete.

меня тут смущает что «that the connection will be closed after completion of the response».

как вариант - можно принимать данные, складывать их куда-либо, и завершать работу скрипта. а другой скрипт, из крона например, или из incron'а, подбирает эти данные и обрабатывает.

isden ★★★★★
()
Ответ на: комментарий от SaBo

а, ну, извини, не понял тебя сразу. Тогда как посоветовали выше - Header шли.

Pinkbyte ★★★★★
()

о, еще мысль пришла. можно же засылать данные не через обычную post форму, а посредством ajax, и на стороне сервера их процессить, не перезагружая страницу.

isden ★★★★★
()
Ответ на: комментарий от isden

как вариант - можно принимать данные, складывать их куда-либо, и завершать работу скрипта. а другой скрипт, из крона например, или из incron'а, подбирает эти данные и обрабатывает.


Ну да, мне и пришла такая мысль... И сделать это через shared memory. Но хотелось бы простого решения :)

о, еще мысль пришла. можно же засылать данные не через обычную post форму, а посредством ajax, и на стороне сервера их процессить, не перезагружая страницу.


Вопрос не в перезагрузке страницы - вопрос в открытом http-соединении. А при Ajax'е http будет открыт столько же, сколько и при обычном посте.

Ну значит буду пробовать заголовки слать... Спасибо за идею :)

P.S. Этот скрипт не для работы браузера с сервером, а для работы двух компонентов системы, которые нужно связать обязательно по HTTP и серверную часть нужно писать обязательно на PHP. Такие пироги.

SaBo ★★
() автор топика
Ответ на: комментарий от SaBo

Нет, по Connection: close не получается.

Что, в общем-то, и логично...

SaBo ★★
() автор топика
Ответ на: комментарий от SaBo

интересно, а что получится, если после приема данных, создавать форк посредством pcntl_fork(), и прибивать родителя через die() ?
в форкнутом процессе уже и производить всю обработку. умрет ли и форк, или станет зомби, или таки отработает?

isden ★★★★★
()
Ответ на: комментарий от isden

интересно, а что получится, если после приема данных, создавать форк посредством pcntl_fork(), и прибивать родителя через die() ?

в форкнутом процессе уже и производить всю обработку. умрет ли и форк, или станет зомби, или таки отработает?

Думаю, что с форком можно реализовать, но тогда зачем мне FastCGI, если я всё равно при каждом запросе форкаться буду?

SaBo ★★
() автор топика

Ты же собираешься принять данные и обрабатывать их «потом», клиент не должен получить ответ в этом же соединении. Так объясни, почему ты так рвёшься делать это «потом» в том же самом скрипте? Положи данные куда удобно, а другой скрипт возьмёт их и обработает. Хочешь кроном, хочешь демоном, вариантов куча. И, думаю, вариант с общей памятью не слишком хорош. Вдруг ты захочешь разнести принимающий данные скрипт, сами данные и процесс обрабатывающий их на разные машины.

Snorg
()
Ответ на: комментарий от Snorg

Ты же собираешься принять данные и обрабатывать их «потом», клиент не должен получить ответ в этом же соединении. Так объясни, почему ты так рвёшься делать это «потом» в том же самом скрипте?


Вообще это аргумент :)
Но дело в том, что данные очень сложно структурированы и парсить их два раза (первый раз: проверить валидность и сохранить, второй раз: получить и обработать) не хотелось бы.
Именно по этому у меня была идея с продолжением работы скрипта после закрытия http. Но вообще, видимо, лучше всего распарсенные данные сериализировать и положить в очередь, а после обработать демоном.

И, думаю, вариант с общей памятью не слишком хорош.


Это так, пример...

SaBo ★★
() автор топика
Ответ на: комментарий от isden

С форком работать не умею.

Но я бы сделал так:
1) Подготовил бы скрипт запускающийся из консоли (php-cli), который бы при запуске принимал один параметр из командной строки (имя файла). Из этого файла считывал сериализованный массив, и обрабатывал бы данные.
2) Принял POST-запрос
3) Сохранил бы пришедшие данные в файл на диске
4) Запустил бы скрипт (см. пункт 0) через вызов shell-exec("(script.php filename &) >> /dev/null 2&>1");
4) Отослал бы пользователю шапочку close с кодом.

valich ★★★
()
Ответ на: комментарий от valich

Но я бы сделал так...


ИМХО вместо файлов лучше заюзать MemcacheQ.
А вообще, честно говоря, я не понял смысла предложенных действий :)

SaBo ★★
() автор топика
Ответ на: комментарий от SaBo

> А вообще, честно говоря, я не понял смысла предложенных действий :)

«Отпустить на волю» скрипт с длительной обработкой данных, а принимающий завершить с разрывом соединения. Хотя конечно некошерно, наплодится их...

valich ★★★
()
Ответ на: комментарий от SaBo

> лучше заюзать MemcacheQ

Зависит от критичности потери части данных до их обработки.
MemcacheQ конечно хорош и стабилен, но... Выдернем сервер из розетки...

valich ★★★
()
Ответ на: комментарий от SaBo

Есть вариант посложнее, чтобы файлы не юзать, и скрипты запущенные не плодить. Демон слушающий файловый сокет. Чтобы не затыкался на прослушке, операцию приема (accept) вынести из основного цикла. Принимать задания в очередь как между обработками, так и в процессе между шагами алгоритма.

Тут зависит конечно от скорости поступления заданий и скорости их обработки. Если разница велика, такого демона недостаточно.

valich ★★★
()
Ответ на: комментарий от valich

MemcacheQ конечно хорош и стабилен, но... Выдернем сервер из розетки...


И у нас всё останется в BerkeleyDB :)

SaBo ★★
() автор топика

Ох, вот не любит наш человек доки читать, а любит придумывать сложные технологичные велосипеды. Прямо на главной странице php-fpm.org:

# Enhancements to FastCGI, such as fastcgi_finish_request() - a special function to finish request & flush all data while continuing to do something time-consuming (video converting, stats processing, etc.)

boombick ★★★★★
()
Ответ на: комментарий от boombick

fastcgi_finish_request() - спасибо. То, что искал :)

SaBo ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.