2011-01-08 9 views
0

Ich habe eine Web-App, die ein paar Prozesse hat, die bis zu 10 Minuten dauern kann. Manchmal werden diese Prozesse von einem Benutzer ausgelöst, und sie benötigen die Ausgabe, während sie verarbeitet wird.forking PHP-Prozess und Bindung an bestimmte Web-Benutzer

Zum Beispiel ist der Benutzer auf der Suche nach ein paar Datensätze, die sie brauchen. Die klicken Sie auf die Schaltfläche zum Abrufen der Datensätze (das ist der Teil, der 10 Minuten dauern kann). Sie können weiterhin arbeiten an anderen Dingen, aber wenn sie klicken Sie zurück, um die Rückgaben anzuzeigen, ist es aktualisiert, wie die Datensätze in das System heruntergeladen werden.

Im Moment ist der Benutzer gesperrt, während der Prozess läuft. Ich weiß über pcntl_fork(), um einen untergeordneten Prozess zu verzweigen, so dass der Benutzer nicht warten muss, bis der lange Prozess abgeschlossen ist.

Ich frage mich, ob es möglich ist, diesen gegabelten Prozess zu dem bestimmten Benutzer, der die Anfrage ausgelöst hat, in einer $_SESSION Variable zu binden, so dass ich den Benutzer aktualisieren kann, wenn der Prozess abgeschlossen ist. Ist dies der beste Weg, um einen Benutzer in einem lang andauernden Prozess zu aktualisieren?

+0

Ich glaube nicht, dass 'pcntl_fork' in diesem Kontext verwendet werden sollte. Forking-Prozesse und Multi-Thread-Webserver sind bekanntlich problematisch. Bei Webanwendungen können Sie stattdessen asynchrone Aktualisierungen über AJAX an den Browser senden. – netcoder

Antwort

4

Ich denke, gearman passt zu Ihren Bedürfnissen. Schauen Sie sich diesen Beispielcode aus dem doc genommen:

<?php 

/* create our object */ 
$gmclient= new GearmanClient(); 

/* add the default server */ 
$gmclient->addServer(); 

/* run reverse client */ 
$job_handle = $gmclient->doBackground("reverse", "this is a test"); 

if ($gmclient->returnCode() != GEARMAN_SUCCESS) 
{ 
    echo "bad return code\n"; 
    exit; 
} 

$done = false; 
do 
{ 
    sleep(3); 
    $stat = $gmclient->jobStatus($job_handle); 
    if (!$stat[0]) // the job is known so it is not done 
     $done = true; 
    echo "Running: " . ($stat[1] ? "true" : "false") . ", numerator: " . $stat[2] . ", denomintor: " . $stat[3] . "\n"; 
} 
while(!$done); 

echo "done!\n"; 

?> 

Wenn Sie die $job_handle in der Sitzung speichern, können Sie die Probe Anpassung an ein Steuerungsskript zu machen.

+0

genial, ich wusste, es gab wahrscheinlich einen besseren Weg, aber ich habe noch nie zuvor von Gearman gehört. – Patrick

+0

+1 für Gearman. –