Как предотвратить время ожидания с асинхронным процессом? - PullRequest
0 голосов
/ 09 сентября 2011

У меня есть простой сценарий создания отчетов, выполнение которого занимает 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

Проблема

  1. Пользователь загружает main.php

    Результат: Отлично.Загружается мгновенно, регистрирует новый запрос отчета и запускает асинхронный вызов, как и ожидалось.Async.php теперь займет 5-10 минут, чтобы завершить отчет.Все в фоновом режиме.

  2. Пользователь загружает main.php через 20 минут (после завершения async.php)

    Результат: Отлично, загружается мгновенно, но пропускает запуск процесса асинхронного отчета, потому что он находится в течение часа после последнего запроса.

  3. Пользователь ждет час и снова загружает main.php

    Результат: Все хорошо, как на шаге 1

    Пока все хорошо, но ...

  4. Теперь пользователь загружает main.php только через 2 минуты после шага 3.

    Результат: FAIL! Загрузка этой страницыбудет зависать, пока не завершится асинхронный процесс, запущенный на шаге 3.Несмотря на то, что таблица mysql со временем журнала запросов обновляется мгновенно на шаге 3. Поэтому на шаге 4 следует просто пропустить вызов и просто отобразить существующий отчет, как на шаге 2.

Что в мире?Что вы рекомендуете для отладки этого?Если другой пользователь хочет запустить тот же отчет, пока пользователь 1 зависает на шаге 4, этот другой пользователь отлично запускает новый отчет.

Я не делаю ничего необычного в своем коде.Просто простые if / then и mysql выбирают поиски.Асинхронный сценарий в значительной степени извлекается из внешних источников, поэтому он не блокирует таблицы mysql, которые могут помешать просмотру времени журнала запросов (полный отчет может выполнить только сто запросов 5 мс за 10 минут, и ни один из них не касается журнала запросов).

Одним из решений является просто хронология процессов, но я обеспокоен тем, что у меня много отчетов, которые никогда не будут видны.И вместо того, чтобы отчет занимал всего 5-10 минут, он увеличился бы в геометрической прогрессии, если бы я выполнял их все чаще.

Итак, придерживаясь моего вышеупомянутого плана атаки (на данный момент), что вы порекомендуете?Почему шаг 2 загружается правильно, а не шаг 4?Существует ли какая-то блокировка скрипта или ограничение на пользователя, о котором я не знаю?

Ответы [ 2 ]

0 голосов
/ 14 сентября 2011

В итоге я принял совет Регилеро.Я установил cron для запуска каждую минуту и ​​собирал все новые запросы в очереди.Это полностью устранило проблему отставания.Спасибо, regilero!

0 голосов
/ 09 сентября 2011

Проблема возникает при создании отчета, верно?

Если это так, вы можете просто создать файл, когда ваш отчет начинает генерацию, и удалить его, когда он закончится, и проверить, существует ли он, перед запуском нового поколения отчета. в вашем файле async.php:

check if 'running.txt' file exists
if it exists:
    display 'report is already running, you need to wait ! '
    stop
else : 
    create file 'running.txt'
    run report
    delete file 'running.txt'
    update last report request table with "complete" status
    the ajax pinger in main.php pulls the "complete" record and triggers notification
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...