正在从后台 Gearman 检索结果 job/task
Retrieving results from background Gearman job/task
主题不言自明,但我绝对需要一双新的眼睛来看待这个问题。
我正在使用 mmoreram/GearmanBundle
Symfony2
捆绑包来发送要执行的作业。所以,到目前为止,我已经成功地发送了一个作业,执行它并获得 return 结果。该部分按预期工作。
但是,我正在尝试与背景相同job/tasks。我知道,在这种情况下,客户端不会等待作业完成,但我希望作业句柄可以帮助我(例如检索作业状态)。
$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
?
更新:
我设法向包中添加了一些代码更改,这使我能够监听作业 return 编辑的数据。那样的话,我也许可以将其保存在数据库中,但是,我的客户(工作创建者)仍然对工作是否真正完成一无所知。
如PHP Manual中所述,只要服务器知道该作业,它就不会完成。
我找到了here这样的解决问题的方法。
当你需要完成一个任务时很方便,答案只需要一会儿。
工人
$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;
}
?>
主题不言自明,但我绝对需要一双新的眼睛来看待这个问题。
我正在使用 mmoreram/GearmanBundle
Symfony2
捆绑包来发送要执行的作业。所以,到目前为止,我已经成功地发送了一个作业,执行它并获得 return 结果。该部分按预期工作。
但是,我正在尝试与背景相同job/tasks。我知道,在这种情况下,客户端不会等待作业完成,但我希望作业句柄可以帮助我(例如检索作业状态)。
$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
?
更新:
我设法向包中添加了一些代码更改,这使我能够监听作业 return 编辑的数据。那样的话,我也许可以将其保存在数据库中,但是,我的客户(工作创建者)仍然对工作是否真正完成一无所知。
如PHP Manual中所述,只要服务器知道该作业,它就不会完成。
我找到了here这样的解决问题的方法。
当你需要完成一个任务时很方便,答案只需要一会儿。
工人
$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;
}
?>