Останавливает ли таймауты PHP людей на одной и той же странице загрузки сети?

Если у меня есть страница PHP, которая выполняет задачу, которая занимает много времени, и я пытаюсь загрузить другую страницу с того же сайта в то же время, эта страница не будет загружаться до истечения времени ожидания первой страницы. Например, если для моего тайм-аута было установлено значение 60 секунд, то я не смог бы загружать любую другую страницу в течение 60 секунд после того, как страница загружалась / истекала длительное время. Насколько я знаю, это ожидаемое поведение.

Я пытаюсь выяснить, повлияет ли неправильный / долго загружаемый скрипт PHP, который создает описанную выше ситуацию, на других людей в той же сети. Я лично думал, что это проблемы с браузером (т.е. если я загрузилhttp://somesite.com/myscript.php в Chrome, и он начинает работать, это магия в фоновом режиме, я не мог тогда загрузитьhttp://somesite.com/myscript2.php пока это не истекло, но яcould загрузить эту страницу в Firefox). Однако я слышал противоречивые заявления, в которых говорилось, что тайм-аут случится со всеми в одной сети (IP-адрес?).

Мой сценарий работает с некоторыми данными, импортированными из sage, и на его запуск уходит довольно много времени - иногда он может истечь до истечения срока действия (то есть, если импорт sage завершится с ошибкой в течение недели), поэтому я запускаю его снова, и он начинает с того места, где он остановился. , Я обеспокоен тем, что другие сотрудники в офисе не смогут получить доступ к сайту, пока он работает.

 Nanne06 июн. 2012 г., 11:40
Не могли бы вы сделать «Я слышал противоречивые заявления»? немного понятнее? Где вы это услышали, почему вы в это поверили, вы можете получить источник?

Ответы на вопрос(2)

Решение Вопроса

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

На самом деле это не «ожидаемое поведение». если ваш веб-сервер не настроен на запуск одного процесса с одним потоком, в этом я сильно сомневаюсь. Это создало бы ситуацию, когда веб-сервер мог обрабатывать только один запрос в любое время, и это затронуло бы всех в сети. Именно поэтому ваш веб-сервер, вероятно, не будет настроен подобным образом - на самом деле я подозреваю, что вы обнаружите, что настроить сервер таким образом невозможно, так как это сделает сервер несколько бесполезным. И перед тем, как некоторые умные alec подключатся к "как насчет Node.js?" - это особый случай, так как я уверен, что вы уже хорошо осведомлены.

Когда у PHP-скрипта открыт сеанс, он имеет эксклюзивную блокировку для файла, в котором хранятся данные сеанса. Это означает, что любой последующий запрос будет заблокирован при вызовеsession_start() в то время как PHP пытается получить эту эксклюзивную блокировку для файла данных сеанса - что он не может, потому что в вашем предыдущем запросе все еще есть такая. Как только ваш предыдущий запрос заканчивается, он снимает блокировку файла, и следующий запрос может быть выполнен. Поскольку сеансы для каждой машины (на самом деле для просмотраsession, как следует из названия, именно поэтому он работает в другом браузере) это не повлияет на других пользователей вашей сети, но оставит ваш сайт настроенным так, что это проблема даже для вас, это плохая практика и ее легко избежать.

Решение этого заключается в том, чтобы позвонитьsession_write_close() как только вы закончили с данными сеанса в данном сценарии. Это приводит к тому, что скрипт закрывает файл сеанса и снимает его блокировку. Вы должны попытаться либо закончить с данными сеанса, прежде чем начать длительный процесс, либо не вызыватьsession_start() до тех пор, пока не завершится.

В теории вы можете позвонитьsession_write_close() а затем позвонитеsession_start() позже в сценарии, но я обнаружил, что PHP иногда демонстрирует ошибочное поведение в этом отношении (я думаю, что это связано с файлами cookie, но не цитируйте меня по этому поводу). Очевидно, обратите внимание на тот факт, что настройка куки изменяет заголовки, поэтому вам нужно позвонитьsession_start() перед выводом любых данных или включением буферизации вывода.

Например, рассмотрим этот скрипт:

<?php

  session_start();

  if (!isset($_SESSION['someval'])) {
    $_SESSION['someval'] = 1;
  } else {
    $_SESSION['someval']++;
  }

  echo "someval is {$_SESSION['someval']}";

  sleep(10);

С помощью приведенного выше сценария вам придется подождать 10 секунд, прежде чем вы сможете сделать второй запрос. Однако, если вы добавите вызовsession_write_close() послеecho линии, вы сможете сделать еще один запрос до того, как предыдущий запрос был завершен.

 06 июн. 2012 г., 12:48
У меня была та же самая проблема, что и описанная ОП, но это решило ее полностью - спасибо за столь обширный ответ!
 06 июн. 2012 г., 13:05
@Jeroen Не беспокойтесь, это относительно простое, но, казалось бы, малоизвестное ограничение сеансов, и люди редко делают скачок между следствием и причиной, поскольку это не сразу очевидно. Один обычно звонитsession_start() в верхней части сценария, что вообще не позволяет сценарию делать что-либо, пока сеанс заблокирован, поэтому вы, естественно, предполагаете, что сервер не запустил сценарий. Эта проблема появлялась здесь раньше, но вы не найдете ее в поиске, потому что люди обычно не упоминают «сессии» в вопросе, плюс вы не знаете, что должны их искать.

Хм ... я не проверял, но я думаю, что каждый запрос к веб-серверу обрабатывается в отдельном потоке. Таким образом, другой запрос не должен быть заблокирован. Просто попробуйте :-) Используйте другой браузер и получите доступ к своей странице, пока работает большой скрипт!

Э-э-э ... Я просто вижу, что это сработало для вас :-) И так должно быть и для других.

Ваш ответ на вопрос