Комментарии 3
Способ с виду рабочий, но у него слишком много недостатков.
Во-первых, держит соединение с сервером. Из-за этого на сервере может быстро исчерпаться пул рабочих потоков. Даже если каждые 2 секунды слать новый ajax-запрос («как там задача?») и получать ответ («пока пыхтит, сделано 30%)», серверу будет легче.
Во-вторых, каждые 2 секунды шлет 4 килобайта несжатого мусора. Немного, конечно, но вдруг у пользователя трафик тарифицируемый? Опять же, короткий запрос-ответ в этом смысле лучше. А еще лучше посчитать по паре ответов примерный ETA и выводить клиенту прогресс-бар, вообще не обращаясь к серверу. Только когда задача, по нашему мнению, досчиталась, тогда и послать запрос «чо как?».
В-третьих, долгоиграющие вещи лучше исполнять на сервере специальными задачами, запускаемыми в фоновом режиме, а не скриптами на PHP. Сервер может быть настроен на автоматическое убиение скриптов, исполняющихся слишком долго, так что пользователь рискует вообще никогда не дождаться результатов.
Во-первых, держит соединение с сервером. Из-за этого на сервере может быстро исчерпаться пул рабочих потоков. Даже если каждые 2 секунды слать новый ajax-запрос («как там задача?») и получать ответ («пока пыхтит, сделано 30%)», серверу будет легче.
Во-вторых, каждые 2 секунды шлет 4 килобайта несжатого мусора. Немного, конечно, но вдруг у пользователя трафик тарифицируемый? Опять же, короткий запрос-ответ в этом смысле лучше. А еще лучше посчитать по паре ответов примерный ETA и выводить клиенту прогресс-бар, вообще не обращаясь к серверу. Только когда задача, по нашему мнению, досчиталась, тогда и послать запрос «чо как?».
В-третьих, долгоиграющие вещи лучше исполнять на сервере специальными задачами, запускаемыми в фоновом режиме, а не скриптами на PHP. Сервер может быть настроен на автоматическое убиение скриптов, исполняющихся слишком долго, так что пользователь рискует вообще никогда не дождаться результатов.
1. Сделано как вариант. Этот метод можно использовать еще и для обработки во время принятия. Например если у нас на JS построена какая нибудь игра или какие нибудь данные, которыми надо оперировать на клиенте, то их можно начать обрабатывать при приеме — лишь каждые 1-2 секунды проверять, что еще пришло.
2. Да про мусор это минус. К слову мне кажется должны быть методы уменьшения этого порога в 4кб. Размер был установлен опытным путем, возможно при другом конфиге или веб сервере можно будет и меньше передавать.
3. Так в моем случае у меня пользователь сначала делает запрос, потом демон обрабатывает этот запрос, а параллельно с демоном пользователь может смотреть через бд процесс выполнения.
К слову вообще по сути это также удобно для каких нибудь чатов. Ведь по сути все равно long-pooling используется. Так ведь можно сделать вот так:
1. Есть соединение через которое пользователь получает сообщения, JS каждую секунду проверяет пришли ли новые данные.
2. Отправляются сообщения через паралелльный запрос AJAX.
По сути эту статью можно брать как дополнение к Long-pooling. Например можно делать запросы с таймаутом по 1-2 минуты, но при этом коннект не прервется сразу при первой передаче. а можно будет просто делать соединение на 2 минуты, и за эти 2 минуты сделать несколько передач, хоть 10, хоть 20, да возможно она все равно одна будет.
К слову лично перед написанием статьи, когда я собственно для задачи все это нашел и собрал вместе для меня стало открытием:
1. То что PHP блокирует сессии, т.е. если есть какие то запросы больше 10-20 секунд, там лучше пытаться закрывать запись, иначе у пользователя это может растянуться в еще больше времени, а перейти он никуда не сможет. Что самое забавное в этой ситуации, я получал интересные казусы связанные с этим. Есть вкладка, где у нас выполняется задача, ну на 10-20 секунд например. Ты пытаешься там тыкнуть в AJAX меню — ничего не работает. Пытаешься открыть сайт в новой вкладке — тоже самое. Причем если в скрипте записано, чтобы он не заканчивал работу после сброса соединение, а скрипт зависнет из за какой либо ошибки, то пользователь вообще не сможет зайти на сайт, просто потому что его сессия будет заблокирована.
2. Я вообще не думал, что можно в процессе передачи данных дергать уже полученные данные до окончания работы.
Не буду спорить с тем, что способ специфичен, и мало где принимим, однако его составные части вполне могут послушить основой для последующих разработок.
2. Да про мусор это минус. К слову мне кажется должны быть методы уменьшения этого порога в 4кб. Размер был установлен опытным путем, возможно при другом конфиге или веб сервере можно будет и меньше передавать.
3. Так в моем случае у меня пользователь сначала делает запрос, потом демон обрабатывает этот запрос, а параллельно с демоном пользователь может смотреть через бд процесс выполнения.
К слову вообще по сути это также удобно для каких нибудь чатов. Ведь по сути все равно long-pooling используется. Так ведь можно сделать вот так:
1. Есть соединение через которое пользователь получает сообщения, JS каждую секунду проверяет пришли ли новые данные.
2. Отправляются сообщения через паралелльный запрос AJAX.
По сути эту статью можно брать как дополнение к Long-pooling. Например можно делать запросы с таймаутом по 1-2 минуты, но при этом коннект не прервется сразу при первой передаче. а можно будет просто делать соединение на 2 минуты, и за эти 2 минуты сделать несколько передач, хоть 10, хоть 20, да возможно она все равно одна будет.
К слову лично перед написанием статьи, когда я собственно для задачи все это нашел и собрал вместе для меня стало открытием:
1. То что PHP блокирует сессии, т.е. если есть какие то запросы больше 10-20 секунд, там лучше пытаться закрывать запись, иначе у пользователя это может растянуться в еще больше времени, а перейти он никуда не сможет. Что самое забавное в этой ситуации, я получал интересные казусы связанные с этим. Есть вкладка, где у нас выполняется задача, ну на 10-20 секунд например. Ты пытаешься там тыкнуть в AJAX меню — ничего не работает. Пытаешься открыть сайт в новой вкладке — тоже самое. Причем если в скрипте записано, чтобы он не заканчивал работу после сброса соединение, а скрипт зависнет из за какой либо ошибки, то пользователь вообще не сможет зайти на сайт, просто потому что его сессия будет заблокирована.
2. Я вообще не думал, что можно в процессе передачи данных дергать уже полученные данные до окончания работы.
Не буду спорить с тем, что способ специфичен, и мало где принимим, однако его составные части вполне могут послушить основой для последующих разработок.
Судя по всему вторая проблема должна решаться так:
Ну либо если не сработает в nginx
Но это если уж совсем радикально, и скорее всего сильно скажется на всем остальном. Но вроде как тот заголовок должен работать начиная с nginx 1.5.6
header('X-Accel-Buffering: no');
Ну либо если не сработает в nginx
proxy_buffering off;
Но это если уж совсем радикально, и скорее всего сильно скажется на всем остальном. Но вроде как тот заголовок должен работать начиная с nginx 1.5.6
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Показываем процесс работы непрерывной задачи на сервере, используя одно соединение