3

已成功将 Gearman 连接到现有 PHP 项目。使用supervisord来保证workers在运行,已经产生了相当不错的效果!

然而,我有一个关键问题,即“setCompleteCallback”根本不起作用。

拆分有点像这样:

客户

$client = new GearmanClient();
$client->addServer();
$client->setCompleteCallback( 
    array( 'LDPE_Service_AWSConnect_Transfer_Target', 'transferComplete' ) );

// push core to S3 bucket
$target = new LDPE_Service_AWSConnect_Transfer_Target( $transaction->id,
    "/usr/local/include/LDP/", LDPE_Service_S3::BUCKET_CORE );

// push S3 bucket to instances
foreach( $aws_target_list as $dns )
{
    $target->addChildRequest( 
        new LDPE_Service_AWSConnect_Transfer_Target( $transaction->id, 
                null, LDPE_Service_S3::BUCKET_CORE, $dns )
    );
}


$client->addTaskBackground( 'transferStart', serialize( $target ) );        
$client->runTasks();

工人

(基本上引导 Zend Framework 环境,并加载 exec 函数)

include 'bootstrap.php';    

ini_set('memory_limit', -1);


$worker = new GearmanWorker();
$worker->addServer();

$worker->addFunction( 'transferStart', array( 
        'LDPE_Service_AWSConnect_Transfer_Target', 'transferStart' ) );

while ($worker->work())
{
    switch( $worker->returnCode() )
    {
        case GEARMAN_SUCCESS:
        break;

        default:
            echo "ERROR RET: " . $worker->returnCode() . "\n";
            exit;   
    }
}

最后,这里是包含所有繁重工作的 LDPE_Service_AWSConnect_Transfer_Target 类。我已经删掉了所有的逻辑,它根本没有触发。

实施方法

class LDPE_Service_AWSConnect_Transfer_Target {

    public static function transferStart( GearmanJob $job )
    {

        $workload   = $job->workload();
        $target     = unserialize( $workload );

        echo "transferStart/begin [ " . 
                $target->getShortRepresentation() . " ]\n";
        // perform a series of actions

        echo "transferStart/complete [ " . 
                $target->getShortRepresentation() . " ]\n"; 
        return serialize( $target );
    }


    public static function transferComplete( GearmanTask $task )
    {
        echo "transferComplete/begin\n";

        $workload       = $task->data();
        $parent_target  = unserialize( $workload );


        echo "transferComplete/complete\n";
    }
}

为了清楚起见,“transferStart/begin”和“transferStart/complete”字符串被正确打印到日志中,但是,transferComplete/begin 永远不会被触发。这是怎么回事?

谢谢!亚历克斯


似乎在后台模式下运行时回调不会触发..

4

2 回答 2

1

在调用 process 函数尝试设置回调

$client->addTaskBackground('my_task', 'payload');
$client->setCompleteCallback('complete');
$client->runTasks();
于 2011-07-05T15:00:51.957 回答
0

我已经尝试过了,它真的归结为让客户端作为 Gearman 任务本身运行。客户端作为浏览器调用页面的一部分被调用。在这种情况下,似乎没有兑现回调。解决方案是将调度回调的客户端移动到 Gearman-run 方法中。我在工作中添加了一个“scheduleXXXX”函数,它几乎称为上面的流程。该函数接收“正常”函数的输入,并进行序列化。

于 2011-07-06T12:52:35.747 回答