1

很简单,我有一个程序需要执行一个大型进程(从 5 秒到几分钟不等),我不想让我的页面等待进程完成加载。

我知道我需要将这个 Gearman 作业作为后台进程运行,但我正在努力确定正确的解决方案,以获取关于工作人员何时真正完成进程的实时状态更新。我使用了 PHP 示例中的以下代码片段:

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

这是可行的,但是当工作人员完成告诉工作要做什么时,它似乎只是将数据返回给客户端。相反我想知道什么时候job完成的字面过程。

我现实生活中的例子:

  1. 从 API 中提取多个数据提要(某些提要比其他提要花费更长的时间)
  2. 加载几个总是快速加载的,在发送到工作队列的部分放置“等待/加载”动画
  3. 当工作完成并完全检索结果时,将动画替换为结果
4

1 回答 1

2

这有点晚了,但我偶然发现了这个问题,寻找相同的答案。我能够一起找到解决方案,所以也许它会帮助其他人。

对于初学者,请参阅GearmanClient::jobStatus上的文档。这将从客户端调用,并且该函数接受一个参数:$job_handle. 您在分派请求时检索此句柄:

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

稍后,您可以通过jobStatus在同一$client对象上调用函数来检索状态:

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

但是,这只有在您使用以下sendStatus方法从您的工作人员中实际更改状态时才有意义:

$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( );
}
  • 在 0.5 之前的 Gearman 版本中,您将使用 GearmanJob::status 方法来设置作业的状态。版本 0.6 到当前 (1.1) 使用上述方法。

  • 另请参阅此问题:Gearman 作业状态问题

于 2013-11-04T10:35:29.883 回答