Почему бесконечная* while ложит сервер

#1 18 ноября 2015 в 14:37
Имеется такой фрагмент кода, который ложит сервер:
  1. while ($data[1] <= $id) {
  2. sleep(1);
  3. $data = unpack('I', shmop_read($memory, 0, 4));
  4. }
Функция ждет когда $data[1] станет больше чем $id чтобы выйти из цикла.

Без icms при чистом выполнении кода сервер спокойно ждет своего момента. В рамках icms сервер виснет.
#2 18 ноября 2015 в 17:34
Даже в гугляндексе не найти.
В других местах (не в icms) этот цикл работает нормально.

Php-гуру, подскажите плиз.
#3 18 ноября 2015 в 17:45
Подождать 20 итераций, сделать вар_дамп $data, выйти
#4 18 ноября 2015 в 17:47
kreator, я конечно не считаю себя гуру, но в таких случаях делают отладку, выводя промежуточные значения в браузер или смотря их в консоли браузера, а если спрашивают, то рассказывают подробно что и где вы делаете. А гадать ни у кого нет желания.
#5 18 ноября 2015 в 19:16
Немного начал вникать. Дело видимо не в цикле.

через js отправляю post запрос к экшену. И пока ответ не получен, другие функции не выполняются, страницы не перезагружаются, и т.д. в итоге получаем 500 т.к. не дождались.

вне icms происходит несколько по-другому. через js отправляю post, чтобы получить ответ. Далее либо получаю ответ, либо так и дождавшись ответа через 40 сек снова отправляю через этот же js новый запрос чтобы не получить ответ что превышено ожидание ответа сервера. Причем в ожидании ответа можно снова и снова делать новые запросы.

в случае с icms то после запроса либо получаю ответ, либо 500, но не могу делать новые запросы.

Пробовал использовать js и php обработчик который внешне работает норм, использовать в системе. Т.е. php ложу в корень сайта, js в компоненте — результат тот же.

Сложно конечно может объяснил.
#6 18 ноября 2015 в 19:21

через js отправляю post запрос к экшену. И пока ответ не получен, другие функции не выполняются, страницы не перезагружаются, и т.д. в итоге получаем 500 т.к. не дождались.

kreator
Видимо запрос выполняется не асинхронный. Попробуйте в $.post параметром указать async:true. Или я просто не понял чего вы хотите и что не получается)
#7 18 ноября 2015 в 19:49
Вот реальный пример:

Страница с любым контентом где есть комментарии. Справа у стенки есть кнопка обновления комментариев, которая через js обновляет список комментариев.

Открываем файл: /system/controllers/comments/action/refresh.php после строки 7 вставляем:
  1. while (1 <= 2) {
  2. $n++;
  3. sleep(1);
  4. if($n==20) break;
  5. }
Теперь когда нажать на кнопку обновления комментариев пойдет запрос к refresh.php комментариев, а он даст задержку в 20 сек. А в это время попробуйте перейти на другую страницу. Пока время не пройдет не получится.

Наверное это точное воспроизведение моей задачи на примере.
#8 18 ноября 2015 в 20:16

Пока время не пройдет не получится.

kreator
так и должно быть. в рамках сессии именно так и будет.

А в это время попробуйте перейти на другую страницу.

kreator
если нажмете стоп в браузере то перейдете.
На эту тему есть директива php — ignore_user_abort

Далее либо получаю ответ, либо так и дождавшись ответа через 40 сек снова отправляю через этот же js новый запрос чтобы не получить ответ что превышено ожидание ответа сервера. Причем в ожидании ответа можно снова и снова делать новые запросы.

kreator
Значит запросы происходят в разных сессиях.

И вообще, в чем главный смысл сего действия?

$data = unpack('I', shmop_read($memory, 0, 4));

kreator
не в смысле что это за конструкция, а в смысле зачем так делаете?

Без icms при чистом выполнении кода сервер спокойно ждет своего момента. В рамках icms сервер виснет.

kreator
соединение так отвалится по таймауту в любом случае — не php, так apache. Хотите реалтайм, используйте сокеты или классический периодический опрос сервера. Или вовсе node.js
#9 18 ноября 2015 в 20:50

так и должно быть. в рамках сессии именно так и будет.

Fuze
вот и вопрос, ведь без icms если чистый скрипт запустить, то ничего не виснет и никто никого не ждет. это обусловлено icms?

если нажмете стоп в браузере то перейдете.
На эту тему есть директива php — ignore_user_abort

Fuze
нет, так сразу и не перейдет. висит.

а в смысле зачем так делаете?

Fuze
пытаюсь сократить количество запросов к БД заменив на long polling

соединение так отвалится по таймауту в любом случае — не php, так apache

Fuze
поэтому не дожидаясь таймаута, скрипт перезапускается. (что невозможно в описанном случае) и снова ждет.

классический периодический опрос сервера

Fuze
так что же все так производительнее на ваш взгляд? запросы каждые 3 секунды от каждого пользователя? или long polling?
#10 18 ноября 2015 в 21:09

вот и вопрос, ведь без icms если чистый скрипт запустить, то ничего не виснет и никто никого не ждет. это обусловлено icms?

kreator
а вы в своем скрипте сессию стартуете? значит работает прерывание запроса.

нет, так сразу и не перейдет. висит.

kreator
обновите зависшую страницу, нажмите стоп и все "отвиснет". После этого перейдете по ссылкам спокойно.

поэтому не дожидаясь таймаута, скрипт перезапускается. (что невозможно в описанном случае) и снова ждет.

kreator
выполняется новый запрос из js, а тот продолжает висеть. И, вероятно, тот предыдущий так и остается висеть, дожидаясь таймаута. Т.е.

запросы каждые 3 секунды от каждого пользователя?

kreator
В вашем случае разницы нет имхо. Только у вас не каждые 3, а каждые 40 секунд обращения.

так что же все так производительнее на ваш взгляд?

kreator
node.js smile

Вы не написали цель вашего действия. Реалтайм комментарии? Так нужно ставить опцию ignore_user_abort(0); и/или отслеживать клики по ссылкам и вешать обработчик (перед переходом по ссылке) типа этого:
  1. if (window.stop !== undefined) {
  2. window.stop();
  3. } else if (document.execCommand !== undefined) {
  4. document.execCommand("Stop", false);
  5. }
Мои ответы актуальны, если я вас правильно понял 😉
#11 18 ноября 2015 в 21:58
Принудительно держать открытым соединение....
Во-первых, это говорит о не верной архитектуре вашего скрипта, во-вторых — создает дополнительную и не нужную нагрузку на сервер.
Вы не можете отвечать в этой теме.
Войдите или зарегистрируйтесь, чтобы писать на форуме.
Используя этот сайт, вы соглашаетесь с тем, что мы используем файлы cookie.