Получение результатов из фоновой работы/задачи Gearman

Тема не требует пояснений, но мне определенно нужен свежий взгляд на это.

Я использую пакет mmoreram/GearmanBundle Symfony2 для отправки заданий на выполнение. Итак, мне удалось отправить задание, выполнить его и вернуть результаты. Эта часть работает, как и ожидалось.

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

$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));

Это выводит следующее:

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

В частности, known => false меня действительно озадачивает. Во время выполнения задания я убедился, что правильно вызываю методы sendStatus и sendComplete.

Таким образом, я думаю, общий вопрос будет таким: после того, как работа будет завершена, будет ли она известна Gearman?

ОБНОВЛЕНИЕ:

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


person Jovan Perovic    schedule 13.01.2016    source источник


Ответы (2)


Как описано в Руководстве по PHP, если задание известно серверу, оно не завершено.

person vranac    schedule 14.01.2016

Я нашел здесь такой вариант решения проблемы.

Удобно, когда нужно выполнить задание, а ответ нужен только на время.

Рабочий

$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); 
}

Клиент

<?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;
}

?>
person Alexey Gavrilov    schedule 08.08.2018