Состояние задания большого запроса, выполненное до завершения запроса

#scala #google-cloud-platform #google-bigquery #cats-effect

# #scala #google-облачная платформа #google-bigquery #кошки-эффект

Вопрос:

У меня есть приложение scala, которое создает таблицу tsv с помощью BigQuery. Когда пользователь пытается получить доступ к данным, я хочу вернуть его, если задание запроса завершено, в противном случае сообщите им, что оно все еще выполняется.

Мое создание задания запроса выглядит следующим образом:

         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 : isDone . По какой-то причине в моем тестировании isDone возвращает true до завершения запроса. Я сам вижу это при проверке консоли BigQuery. Это приводит к тому, что запрос пользователя всегда останавливается до завершения запроса, вместо того, чтобы возвращать сообщение, как предполагалось.

Как это задание может быть завершено, пока запрос все еще выполняется? Я упускаю какое-то различие между заданиями и запросами? Или есть что-то еще, что я пропустил? Спасибо за любые предложения, которые у вас могут быть.

Ответ №1:

jobs.getQueryResults имеет необязательный timeoutMs параметр, который управляет его зависающей семантикой GET. Он ожидает завершения задания до указанного интервала или 10 секунд, если не указано. Если задание завершено, оно возвращается немедленно независимо от этого.

Если вы установите время ожидания равным нулю, ответ будет возвращен немедленно, и вы можете проверить статистику результатов, чтобы увидеть, завершено ли задание. Если это так, ответ должен также содержать схему и первую страницу строк данных.

Дополнительная информация из ссылки REST: https://cloud.google.com/bigquery/docs/reference/rest/v2/jobs/getQueryResults

Комментарии:

1. Спасибо за ответ. В моей текущей реализации запрос зависает до завершения запроса, что длится дольше 10 секунд. Есть идеи, почему это так? Кроме того, почему isDone вычисляется как true, пока запрос все еще выполняется?

2. Недостаточно информации. Запрос заканчивается ошибкой? Это был бы случай, когда задание находится в состоянии done, но результатов запроса нет. Аналогично, запрос SQL DDL будет делать то же самое, поскольку DDL также не возвращает результатов.

3. Что касается продолжительности выполнения, вы полагаетесь на абстракцию библиотеки, которая, вероятно, опрашивает от вашего имени, а не на контракт API низкого уровня.

4. Задание выполняется успешно, и поскольку оно запрашивает большую таблицу, для завершения требуется всего несколько минут. bigQueryService.getMyJob возвращает только объект задания, любой опрос выполняется через java-клиент BigQuery. isDone это метод, предоставляемый для объекта задания Google.

5. Я пытаюсь установить maxWaitTime значение 0 сек в качестве параметра для getQueryResults , а затем проверить схему, чтобы убедиться, что она завершена. Я сообщу, если это решит проблему.