我正在尝试在PHP(Laravel)中使用Shopify GraphQL API进行管理。
与REST api相比,GraphQL api中的速率限制和节流的作用不同,REST api是根据查询的 cost 计算的。
需要牢记的几点:
我要传递给api的查询的估计费用为 502 ,由 requestedQueryCost 表示。而 actualQueryCost 代表api针对特定商店返回的实际响应。
在上面的快照中,对于具有大量订单的商店,其最坏的情况 requestedQueryCost 等于 acutalQueryCost 。
现在,执行此查询时,我消耗了502点,还剩498点,经过1秒,添加了50点= 548 ,并且我可以进行第二次api调用以获取第二页数据。在第二次api调用后,我剩下的点数减少了,因此我必须将 sleep 放置1或2秒钟才能获得要进行api调用的点数。
在快照所示的情况下,我必须放置 10秒睡眠等待时间才能恢复 500点以便进行下一个api调用。
问题:如何最好地决定不同商店的睡眠(等待)时间?我们不希望所有商店都等待10秒,即使它们的查询成本较低。
注意:有关代码参考,请参见下面的答案。
答案 0 :(得分:0)
您会清楚地收到每家商店的费用查询电话。如果一家商店为零,那么您可能还有1000个在另一家商店等您。您应该确保您的调用机制明确无误!每个商店只能睡一个线程。您应该能够将请求分配给线程,这样,即使它休眠了,您仍然可以与其他线程一起操作。如果PHP用分配给所有请求的一个线程来操作,那我会很不高兴。那将是1982年的计算结果!
答案 1 :(得分:0)
下面是我的解决方案草稿,仍在寻找有关如何有效处理该问题的专家意见,以便根据数据量,每个商店都必须等待应得的时间。请指教。
public function getRequiredOrders()
{
$firstRequestTimeStamp = now();
$ordersGraph = $this->shop->api()->graph($this->firstQuery())->body->orders;
$this->transform($ordersGraph); //transforming to required format
$previousRequestTimeStamp = $firstRequestTimeStamp;
while($ordersGraph->pageInfo->hasNextPage) {
$nextRequestTimeStamp = now();
$timeElapsed = $nextRequestTimeStamp->diffInSeconds($previousRequestTimeStamp);
$restoredPoints = $timeElapsed * 50; //50 points are restored every 1 second
$pointsLeft = $this->shop->api()->getApiCalls('graph', 'left');
$totalPointsLeft = $pointsLeft + $restoredPoints;
if($totalPointsLeft >=502){ //one must know the maximum cost of their query
$lastEdgeCursor = end($ordersGraph->edges)->cursor;
$nextQuery = $this->nextQuery($lastEdgeCursor);
$previousRequestTimeStamp = $nextRequestTimeStamp;
$ordersGraph = $this->shop->api()->graph($nextQuery)->body->orders;
$this->transform($ordersGraph);
}else{
sleep(1);
continue;
}
}
return $this->allOrders;
}