Google示例代码#1
$queryResults = $bigQuery->runQuery('SELECT commit FROM [bigquery-public-data:github_repos.commits] LIMIT 100');
$isComplete = $queryResults->isComplete();
while (!$isComplete) {
sleep(1); // let's wait for a moment...
$queryResults->reload(); // trigger a network request
$isComplete = $queryResults->isComplete(); // check the query's status
}
foreach ($queryResults->rows() as $row) {
echo $row['commit'];
}
在示例代码#1中,如果Google Bigquery方面存在一些错误,那么php脚本将陷入无限循环,对吗?
Google示例代码#2
$queryResults = $bigQuery->runQuery(
$query,
['useLegacySql' => $useLegacySql]);
# [END run_query]
# [START print_results]
if ($queryResults->isComplete()) {
$i = 0;
$rows = $queryResults->rows();
foreach ($rows as $row) {
printf('--- Row %s ---' . PHP_EOL, ++$i);
foreach ($row as $column => $value) {
printf('%s: %s' . PHP_EOL, $column, $value);
}
}
printf('Found %s row(s)' . PHP_EOL, $i);
} else {
throw new Exception('The query failed to complete');
}
在示例代码#2中,bigquery可能仍然在它完成之前运行,但是我们的php代码可能已经过早地抛出了错误的异常。
正确的解决方案是否如下所示?
$counter = 0;
while (!$isComplete && $counter < 100) {
sleep(1); // let's wait for a moment...
$queryResults->reload(); // trigger a network request
$isComplete = $queryResults->isComplete(); // check the query's status
#counter++;
}
因此我们将给出大量的时间来完成查询,但我们只会等待一段合理的时间才能抛出错误异常。
答案 0 :(得分:1)
您的提案看起来很合理。虽然您可能希望将jobid放入队列,并让threadpool线程/计时器定期检查它,而不是仅在主线程中阻塞和休眠。 (我不熟悉php,所以请原谅我,如果你没有这种语言的实用工具)
答案 1 :(得分:1)
最近已添加ExponentialBackoff,请查看最新版本的PHP库
您的代码将类似于:
$job = $bigQuery->runQueryAsJob($query);
$backoff = new ExponentialBackoff(8);
$backoff->execute(function () use ($job) {
$job->reload();
if (!$job->isComplete()) {
throw new \Exception();
}
});
if (!$job->isComplete()) {
$this->e('Job failed to complete within the allotted time.');
return false;
}
$queryResults = $job->queryResults();
if ($queryResults->isComplete()) {
$i = 0;
$rows = $queryResults->rows();