我有一个php应用程序,可以从我们的服务器获取部件号请求。在那一刻,我们联系第三方API以收集定价信息,以确保我们拥有该特定请求的最新定价。有时第三方API速度很慢或者可能已关闭,因此我们有一个数据库,可存储我们可用作后备的每个特定部件号的最新定价请求。我想使用Gearman并行地向第三方API和数据库运行请求。这是一个想法:
使用gearman,我的想法是在前台运行两个任务并在setCompleteCallback()调用中中断runTasks(),或者在后台运行它们并在单独的循环中检查两个任务并使用jobStatus()检查任务。
不幸的是,我无法获得任何一条路由,但仍能访问结果数据。有没有更好的方法,或者是否存在某些人如何使这项工作成为现实的例子?
答案 0 :(得分:0)
我认为您已经描述了单个阻止问题,即第三方API查找的结果。从我的角度来看,有两种方法可以解决这个问题,要么你可以完全放弃尝试,如果你决定你已经没时间了,或者你可以向客户报告你用完了时间,但仍然继续查找,只是为了更新你的本地缓存,以防万一它的响应速度比你想要的慢。我将描述如何处理前一个问题,因为这会更容易。
从客户端:
$request = array(
'productId' => 5,
);
$client = new GearmanClient( );
$client->addServer( '127.0.0.1', 4730 );
$results = json_decode($client->doNormal('apiPriceLookup', json_encode( $request )));
if($results && property_exists($results->success) && $results->success) {
// Use local data
} else {
// Use fresh data
}
这将在作业服务器上创建一个函数名为'apiPriceLookup'
的作业,并将包含产品ID 5
的工作负载数据传递给它。它将等待结果返回,并检查success
属性。如果它存在且为真,则api查找成功。
这个想法是在worker任务中设置超时条件,这完全取决于你如何实现API查找。如果你正在使用cURL(或cURL的一些包装器),你可以看到如何检测超时here的答案。
从工人方面来说:
$worker= new GearmanWorker();
$worker->addServer();
$worker->addFunction("apiPriceLookup", "apiPriceLookup", $count);
while ($worker->work());
function apiPriceLookup($job) {
$payload = json_decode($job->workload());
try {
$results = [
'data' => PerformApiLookupForProductId($payload->productId),
'success' => true,
];
} catch(Exception $e) {
$results = ['success' => false];
}
return json_encode($results);
}
这只是创建一个GearmanWorker
对象,并为其订阅apiPriceLookup
的功能。只要客户端向作业服务器提交任务,它就会调用函数apiPriceLookup
。该函数调用另一个函数PerformApiLookupForProductId
,该函数应该被写入,以便在发生超时条件时抛出异常。
我认为这不会被视为使用异常来控制逻辑流程,我认为超时条件通常是异常(或应该是)事件。例如,Guzzle将抛出GuzzleHttp\Exception\RequestException
when it has decided to timeout。