Jovan Perovic
Jovan Perovic

Reputation: 20191

Retrieving results from background Gearman job/task

Subject is quite self-explanatory, but I definitely need a fresh pair of eyes on this.

I am using mmoreram/GearmanBundle Symfony2 bundle to send jobs to execute. So, far I have managed to send a job, execute it and return results. That part works as expected.

However, I am trying to the same with background job/tasks. I know that, in this scenario, client does not wait for job to complete, but I was hoping that job handle can help me with that (e.g. retrieve job status).

$gearman = $this->get('gearman');
$jobId = $gearman->doHighBackgroundJob("CsvWorker~parseCsv", json_encode(["foo", "bar", "123"]));
sleep(3);

// At this point, job has completed for sure (it's very simple)
var_dump($jobId);
var_dump($gearman->getJobStatus($jobId));

This outputs the following:

string 'H:localhost.localdomain:10' (length=26)

object(Mmoreram\GearmanBundle\Module\JobStatus)[410]
  private 'known' => boolean false
  private 'running' => boolean false
  private 'completed' => int 0
  private 'completionTotal' => int 0

The known => false, in particular, really puzzles me. During the job execution, I made sure to invoke correctly sendStatus and sendComplete methods.

So, I guess, a general question would be: once the job has completed, is it still known to Gearman?

UPDATE:

I managed to add some code changes to the bundle which allowed me to listen for data being returned by job. That way, I may be able to persist that in database, however, my client (job creator) is still pretty much left in the dark on whether the job has actually finished.

Upvotes: 0

Views: 1464

Answers (2)

Alexey Gavrilov
Alexey Gavrilov

Reputation: 59

I found here such an option for solving the problem.

It is convenient when you need to complete a task, and the answer is needed only for a while.

Worker

$gmworker = new GearmanWorker(); 
$gmworker->addServer(); 
$gmworker->addFunction("long_running_task", "long_running_task_fn"); 


print "Waiting for job...\n"; 
while($gmworker->work()) { 
    if ($gmworker->returnCode() != GEARMAN_SUCCESS) { 
      echo "return_code: " . $gmworker->returnCode() . "\n"; 
      break; 
    } 
} 


function long_running_task_fn($job) { 
    $mc = memcache_connect('localhost', 11211); 
    $result = 1; 
    $n = $job->workload(); 
    for ($i = 1; $i <= $n; $i++) { 
        $result *= $i; 
        $job->sendStatus($i, $n); 
        sleep(1); 
    } 
    memcache_set($mc, $job->handle(), $result); 
}

Client

<?php

if ($_POST['start']) {
        $gmc = new GearmanClient();
        $gmc->addServer();
        $handle = $gmc->doBackground('long_running_task', '10');
        header('Location: /client.php?handle='.urlencode($handle));
}

if ($_GET['handle']) {
        $handle = $_GET['handle'];
        $gmc = new GearmanClient();
        $gmc->addServer();
        $status = $gmc->jobStatus($handle);
}

function get_result($handle) {
        $mc = memcache_connect('localhost', 11211);
        $reply = memcache_get($mc, $handle);
        memcache_close($mc);
        return $reply;
}

?>

Upvotes: 2

vranac
vranac

Reputation: 94

As described in PHP Manual, as long as the job is known to the server, it is not completed.

Upvotes: 1

Related Questions