У меня есть простой сценарий создания отчетов, выполнение которого занимает 5-10 минут.Он запускается асинхронно с помощью вызова fsockopen для запуска в фоновом режиме.Это прекрасно работает иногда.Но если пользователь обновляет главную страницу, в то время как асинхронный отчет, запущенный из предыдущей загрузки страниц, все еще работает, главная страница зависает, пока не завершится асинхронный процесс после первой загрузки страницы.
Ниже приведена грубая логика, лежащая в основе моих сценариев,далее следуют подробности того, что работает, а что нет ...
main.php
if last report was already run within the hour (mysql select last report time)
display existing report, that's it.
else
log latest report process request
run report asynchronously in the background (async.php)
notification when updated report is completed (simple ajax pinger every 10s)
async.php
run report
update last report request table with "complete" status
the ajax pinger in main.php pulls the "complete" record and triggers notification
Проблема
Пользователь загружает main.php
Результат: Отлично.Загружается мгновенно, регистрирует новый запрос отчета и запускает асинхронный вызов, как и ожидалось.Async.php теперь займет 5-10 минут, чтобы завершить отчет.Все в фоновом режиме.
Пользователь загружает main.php через 20 минут (после завершения async.php)
Результат: Отлично, загружается мгновенно, но пропускает запуск процесса асинхронного отчета, потому что он находится в течение часа после последнего запроса.
Пользователь ждет час и снова загружает main.php
Результат: Все хорошо, как на шаге 1
Пока все хорошо, но ...
Теперь пользователь загружает main.php только через 2 минуты после шага 3.
Результат: FAIL! Загрузка этой страницыбудет зависать, пока не завершится асинхронный процесс, запущенный на шаге 3.Несмотря на то, что таблица mysql со временем журнала запросов обновляется мгновенно на шаге 3. Поэтому на шаге 4 следует просто пропустить вызов и просто отобразить существующий отчет, как на шаге 2.
Что в мире?Что вы рекомендуете для отладки этого?Если другой пользователь хочет запустить тот же отчет, пока пользователь 1 зависает на шаге 4, этот другой пользователь отлично запускает новый отчет.
Я не делаю ничего необычного в своем коде.Просто простые if / then и mysql выбирают поиски.Асинхронный сценарий в значительной степени извлекается из внешних источников, поэтому он не блокирует таблицы mysql, которые могут помешать просмотру времени журнала запросов (полный отчет может выполнить только сто запросов 5 мс за 10 минут, и ни один из них не касается журнала запросов).
Одним из решений является просто хронология процессов, но я обеспокоен тем, что у меня много отчетов, которые никогда не будут видны.И вместо того, чтобы отчет занимал всего 5-10 минут, он увеличился бы в геометрической прогрессии, если бы я выполнял их все чаще.
Итак, придерживаясь моего вышеупомянутого плана атаки (на данный момент), что вы порекомендуете?Почему шаг 2 загружается правильно, а не шаг 4?Существует ли какая-то блокировка скрипта или ограничение на пользователя, о котором я не знаю?