1

Very simply, I have a program that needs to perform a large process (anywhere from 5 seconds to several minutes) and I don't want to make my page wait for the process to finish to load.

I understand that I need to run this gearman job as a background process but I'm struggling to identify the proper solution to get real-time status updates as to when the worker actually finishes the process. I've used the following code snippet from the PHP examples:

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";

and this works, however it appears that it just returns data to the client when the worker finished telling the job what to do. Instead I want to know when the literal process of the job finished.

My real-life example:

  1. Pull several data feeds from an API (some feeds take longer than others)
  2. Load a couple of the ones that always load fast, place a "Waiting/Loading" animation on the section that was sent off to a worker queue
  3. When the work is done and the results have been completely retrieved, replace the animation with the results
Jared Eitnier
  • 7,012
  • 12
  • 68
  • 123

1 Answers1

2

This is a bit late, but I stumbled across this question looking for the same answer. I was able to get a solution together, so maybe it will help someone else.

For starters, refer to the documentation on GearmanClient::jobStatus. This will be called from the client, and the function accepts a single argument: $job_handle. You retrieve this handle when you dispatch the request:

$client = new GearmanClient( );
$client->addServer( '127.0.0.1', 4730 );
$handle = $client->doBackground( 'serviceRequest', $data );

Later on, you can retrieve the status by calling the jobStatus function on the same $client object:

$status = $client->jobStatus( $handle );

This is only meaningful, though, if you actually change the status from within your worker with the sendStatus method:

$worker = new GearmanWorker( );
$worker->addFunction( 'serviceRequest', function( $job ) {
    $max = 10;
    // Set initial status - numerator / denominator
    $job->sendStatus( 0, $max );

    for( $i = 1; $i <= $max; $i++ ) {
        sleep( 2 ); // Simulate a long running task
        $job->sendStatus( $i, $max );
    }

    return GEARMAN_SUCCESS;
} );

while( $worker->work( ) ) {
    $worker->wait( );
}
  • In versions of Gearman prior to 0.5, you would use the GearmanJob::status method to set the status of a job. Versions 0.6 to current (1.1) use the methods above.

  • See also this question: Problem With Gearman Job Status

Community
  • 1
  • 1
Jeff Lambert
  • 24,395
  • 4
  • 69
  • 96
  • I'm sure this is probably right. For background processing now, I personally use [Pusher](http://pusher.com) and [IronWorker](http://www.iron.io/worker) with great success. – Jared Eitnier Jul 03 '14 at 21:57