Scala 大查询作业状态在查询完成之前完成

Scala 大查询作业状态在查询完成之前完成,scala,google-cloud-platform,google-bigquery,cats-effect,Scala,Google Cloud Platform,Google Bigquery,Cats Effect,我有一个scala应用程序,它使用BigQuery创建tsv表。当用户试图访问数据时,如果查询作业完成,我希望返回数据,否则告诉他们数据仍在运行 我的查询作业创建如下所示: bigQuery.create( JobInfo.of( QueryJobConfiguration .newBuilder(mySql) .setAllowLargeResults(true)

我有一个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)
  }
}
获取数据的方法如下所示:

        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效果IO进行评估。我的问题是,作业上的
getQueryResults
方法会暂停,直到查询完成。我试图通过检查BQ作业上的另一种方法来防止这种情况:
isDone
。在我的测试中,由于某种原因,
isDone
在查询完成之前返回true。我在检查BigQuery控制台时看到了这一点。这会导致用户的请求总是暂停,直到查询完成,而不是按预期返回消息


如何在查询仍在运行时完成作业?我是否遗漏了作业和查询之间的一些区别?还是我还错过了什么?感谢您提供的任何建议。

作业。getQueryResults
有一个可选的
timeoutMs
参数,用于控制其挂起GET语义。它等待作业完成,直到指定的时间间隔或10秒(如果未指定)。如果作业完成,它将立即返回

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


来自REST参考的其他信息:

感谢您的回复。在我当前的实现中,请求将一直挂起,直到查询完成,这超过10秒。你知道为什么会这样吗?另外,为什么
isDone
在查询仍在运行时计算为true?信息不足。查询是否以错误结尾?在这种情况下,作业处于“完成”状态,但没有可用的查询结果。类似地,SQL DDL查询的作用与DDL也不返回结果的作用相同。就运行时间而言,您依赖的是可能代表您进行轮询的库抽象,而不是低级API协定。作业运行成功,因为它查询大型表只需几分钟即可完成
bigQueryService.getMyJob
只返回作业对象,任何轮询都是通过BigQuery的java客户端完成的
isDone
是google为作业对象提供的一种方法。我正在尝试将
maxWaitTime
设置为0秒,作为
getQueryResults
的参数,然后检查架构是否完成。如果问题解决了,我会向你汇报。