0

我有一个使用 BigQuery 创建 tsv 表的 scala 应用程序。当用户尝试访问数据时,如果查询作业完成,我想返回它,否则告诉他们它仍在运行。

我的查询作业创建如下所示:

        bigQuery.create(
          JobInfo.of(
            QueryJobConfiguration
              .newBuilder(mySql)
              .setAllowLargeResults(true)
              .setDestinationTable(TableId.of("MyReports", s"${tableName}_$random".replace("-", "_")))
              .setWriteDisposition(JobInfo.WriteDisposition.WRITE_TRUNCATE)
              .setCreateDisposition(JobInfo.CreateDisposition.CREATE_IF_NEEDED)
              .setUseLegacySql(false)
              .build()
          )
        )

获取数据的方法如下所示:

override def getData(jobId: String): IO[Either[Throwable, String]] = {
  bigQueryService.getMyJob(jobId).map {
    case Right(None) | Right(Some(null)) => Right("Data not found, check provided job name")
    case Right(Some(r)) =>
      if (r.isDone) {
        Try(r.getQueryResults()
        .iterateAll()
        .asScala
        .map(_.asScala.map(_.getValue.toString).mkString("\t"))
        .mkString("\n")
        ).toEither
      } else {
        Right(s"Job not completed, current status is ${r.getStatus.getState.toString}")
      }
    case Left(err: Throwable) => Left(err)
  }
}

我在计算结束时使用 Cats Effect IO 进行评估的地方。我的问题是getQueryResults作业上的方法会停止,直到查询完成。我试图通过检查 BQ Job: 上的另一种方法来防止这种情况发生isDone。出于某种原因,在我的测试中,isDone在查询完成之前返回 true。我在检查 BigQuery 控制台时看到了这一点。这会导致用户的请求始终停止,直到查询完成,而不是按预期返回消息。

如何在查询仍在运行时完成作业?我错过了工作和查询之间的一些区别吗?或者还有什么我错过的?感谢您提出的任何建议。

4

1 回答 1

1

jobs.getQueryResults有一个可选timeoutMs参数,用于控制其悬挂的 GET 语义。如果未指定,它会在指定的时间间隔或 10 秒内等待作业完成。如果作业完成,则无论如何都会立即返回。

如果您将超时设置为零,它将立即返回响应,您可以检查结果统计信息以查看作业是否完成。如果是这样,则响应还应包含架构和数据行的第一页。

来自 REST 参考的其他信息:https ://cloud.google.com/bigquery/docs/reference/rest/v2/jobs/getQueryResults

于 2020-12-16T17:40:59.423 回答