PHP: cómo devolver información a una secuencia de comandos en espera y continuar procesando


6

Supongamos que hay dos scripts, Requester.php y Provider.php, y el Solicitante requiere que el proveedor procese y realiza una solicitud http (Provider.php? Data = " datos"). En esta situación, el Proveedor encuentra rápidamente la respuesta, pero para mantener el sistema debe realizar varias actualizaciones en toda la base de datos. ¿Hay alguna manera de devolver inmediatamente el valor a Solicitante y luego continuar el procesamiento en el Proveedor?

pseudo código

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

Básicamente, desea señalar el final del 1 proceso (volver al original Requester.php) y generar un nuevo proceso (finalizar Provider.php). Probablemente haya una manera más elegante de llevarlo a cabo, pero he logrado esto de dos maneras diferentes. Todos ellos básicamente resultan en la ejecución de un comando para cancelar el segundo proceso.

añadiendo lo siguiente > /dev/null 2>&1 & al final de su comando permitirá que se ejecute en segundo plano sin inhibir la ejecución real de su script actual

Algo parecido a lo siguiente puede funcionar para usted:

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

- aunque también podría hacerlo como un proceso PHP de línea de comandos.

También podría guardar la información que necesita procesarse y manejar el procesamiento restante en un trabajo cron que recrea el mismo tipo de funcionalidad sin la necesidad de ejecutar.


2

Usted puede vaciar el búfer de salida con el comando flush().
Leer los comentarios en el PHP manual para obtener más información


0

Dividir el Proveedor en dos: ProviderCore y ProviderInterface. En ProviderInterface simplemente haga la parte "rápida y fácil", también guarde una marca en la base de datos que indique que la solicitud reciente aún no se ha procesado. Ejecute ProviderCore como un trabajo cron que busca ese indicador y completa el procesamiento. Si no hay nada que hacer, ProviderCore terminará e intentará de nuevo en (digamos) 2 minutos.


1

Creo que necesitará que el proveedor envíe los datos (asegúrese de enjuagar), y luego en el Solicitante, use fopen/fread para leer una cantidad esperada de datos, para que pueda soltar la conexión al Proveedor y continuar Si no especifica una cantidad de datos para esperar, creo que el solicitante se quedaría esperando que el proveedor cerrara la conexión, lo que probablemente no ocurra hasta que se termine su ejecución (es decir, todo el trabajo secundario intensivo) las tareas están completas). Necesitará probar algunos POC.

Buena suerte.


2

Uso this code para ejecutar un proceso en segundo plano (funciona en Linux).

El proceso se ejecuta con su salida redirigida a un archivo.

De esta forma, si necesito mostrar el estado en el proceso, solo es cuestión de escribir una pequeña cantidad de código para leer y mostrar el contenido del archivo de salida.

Me gusta este enfoque porque significa que puede cerrar completamente el navegador y volver fácilmente más tarde para verificar el estado.


0

Voy a estar en una extremidad aquí, pero tal vez deberías probar cURL o utilizar un socket para actualizar el solicitante?


0

Se podría iniciar otro proceso de php en Provider.php usando 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; 

}