谷歌bigquery runquery样本和睡眠时使用的正确方法来检查queryresult

时间:2017-03-08 19:07:51

标签: google-bigquery

Google示例代码#1

https://googlecloudplatform.github.io/google-cloud-php/#/docs/v0.21.1/bigquery/bigqueryclient?method=runQuery

$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

https://github.com/GoogleCloudPlatform/php-docs-samples/blob/master/bigquery/api/src/functions/run_query.php

$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++;
}

因此我们将给出大量的时间来完成查询,但我们只会等待一段合理的时间才能抛出错误异常。

2 个答案:

答案 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();