我有一个scala应用程序,它使用BigQuery创建一个tsv表。当用户尝试访问数据时,如果查询作业已完成,我希望返回该数据,否则告诉他们该作业仍在运行。
我创建的查询作业如下所示:
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控制台时,我自己也看到了这一点。这会导致用户的请求总是延迟,直到查询完成,而不是像预期的那样返回消息。
如何在查询仍在运行的情况下完成作业?我是否错过了作业和查询之间的某些区别?或者我还漏掉了什么?感谢您的任何建议。
发布于 2020-12-17 01:40:59
jobs.getQueryResults有一个可选的timeoutMs参数,该参数控制其挂起的GET语义。它等待作业完成时间不超过指定的时间间隔,如果未指定,则等待10秒。如果作业已完成,则无论如何,它都会立即返回。
如果您将超时设置为零,它将返回立即响应,并且您可以检查结果统计信息,以查看作业是否完成。如果是,则响应还应包含架构和数据行的第一页。
来自REST参考的其他信息:https://cloud.google.com/bigquery/docs/reference/rest/v2/jobs/getQueryResults
https://stackoverflow.com/questions/65327651
复制相似问题