主题是不言自明的,但我肯定需要一双新的眼睛。
我正在使用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
方法。
所以,我想,一般的问题是:一旦工作完成,{strong> 仍然知道到Gearman
?
更新:
我设法在捆绑包中添加了一些代码更改,这使我可以监听作业返回的数据。这样,我可能能够在数据库中坚持这一点,但是,我的客户(工作创建者)在工作是否真正完成时仍然处于黑暗状态。
答案 0 :(得分:1)
如PHP Manual所述,只要服务器知道该作业,就不会完成。
答案 1 :(得分:1)
我发现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;
}
?>