PHP: как вернуть информацию в сценарий ожидания и продолжить обработку


6

Предположим, что есть два сценария Requester.php и Provider.php, а Requester требует обработки от Поставщика и делает ему http-запрос (Provider.php? Data = " данные"). В этой ситуации поставщик быстро находит ответ, но для поддержания системы необходимо выполнять различные обновления по всей базе данных. Есть ли способ немедленно вернуть значение Requester, а затем продолжить обработку в Provider.

псевдопользователей Код

Provider.php 
{ 
    $answer = getAnswer($_GET['data']); 
    echo $answer; 
    //SIGNAL TO REQUESTER THAT WE ARE FINISHED 
    processDBUpdates(); 
    return; 
} 
1

Вы в основном хотите сигнализировать о завершении 1 процесса (возврат к оригиналу Requester.php) и создать новый процесс (закончить Provider.php). Вероятно, есть более элегантный способ снять это, но я справился с этим несколькими разными способами. Все они в основном приводят к выполнению команды, чтобы отключить второй процесс.

добавив следующую > /dev/null 2>&1 & до конца вашей команды позволит ему работать в фоновом режиме, не препятствуя фактическое выполнение текущего скрипта

Что-то вроде следующего может работать для вас:

exec("wget -O - \"$url\" > /dev/null 2>&1 &"); 

- хотя вы могли бы сделать это и как процесс командной строки PHP.

Вы также можете сохранить информацию, которая должна быть обработана, и обработать оставшуюся обработку в задании cron, которое повторно создает такую ​​же функциональность без необходимости выполнять exec.


2

Вы можете очистить буфер вывода с помощью команды Flush().
Читать комментарии в PHP manual для получения дополнительной информации


0

Разбить Provider в двух: ProviderCore и ProviderInterface. В ProviderInterface просто выполните «быструю и легкую» часть, также сохраните флаг в базе данных, что недавний запрос еще не обработан. Запустите ProviderCore как задание cron, которое выполняет поиск этого флага и завершает обработку. Если нечего делать, ProviderCore прекратит и повторит попытку (скажем) 2 минуты.


1

Я думаю, вам понадобится провайдер для отправки данных (обязательно для очистки), а затем в Requester используйте fopen/fread для чтения ожидаемого количества данных, чтобы вы могли отказаться от подключения к Провайдера и продолжить. Если вы не укажете количество ожидаемых данных, я бы подумал, что запросчик будет сидеть там, ожидая, пока провайдер завершит соединение, что, вероятно, не произойдет до конца его запуска (т. Е. Все вторичные интенсивные работы задачи полны). Вам нужно попробовать несколько POC ..

Удачи.


2

Использую this code для запуска процесса в фоновом режиме (работает в Linux).

Процесс запускается с выходом, перенаправленным в файл.

Таким образом, если мне нужно отобразить состояние процесса, это всего лишь вопрос написания небольшого количества кода для чтения и отображения содержимого выходного файла.

Мне нравится этот подход, потому что это означает, что вы можете полностью закрыть браузер и легко вернуться позже, чтобы проверить статус.


0

Я выхожу на конечность здесь, но, возможно, вам стоит попробовать cURL или использовать сокет для обновления запрашивающего?


0

Вы могли бы начать другой процесс PHP в Provider.php с помощью pcntl_fork()

Provider.php 
{ 
    // Fork process 
    $pid = pcntl_fork(); 

    // You are now running both a daemon process and the parent process 
    // through the rest of the code below 

    if ($pid > 0) { 
     // PARENT Process 
     $answer = getAnswer($_GET['data']); 
     echo $answer;  
     //SIGNAL TO REQUESTER THAT WE ARE FINISHED 
     return; 
    } 

    if ($pid == 0) { 
     // DAEMON Process 
     processDBUpdates(); 
     return; 
    } 

    // If you get here the daemon process failed to start 
    handleDaemonErrorCondition(); 
    return; 

}