Поделиться через


Длительные операции в пакете SDK Azure для Java

В этой статье представлен обзор использования длительных операций с пакетом SDK Azure для Java.

Для выполнения некоторых операций в Azure может потребоваться длительное время. Эти операции находятся вне стандартного стиля HTTP быстрого запроса или потока ответа. Например, копирование данных из исходного URL-адреса в большой двоичный объект хранилища или обучение модели распознавания форм — это операции, которые могут занять несколько секунд до нескольких минут. Такие операции называются операциями Long-Running и часто сокращены как LRO. LRO может занять секунды, минуты, часы, дни или больше времени, в зависимости от запрошенной операции и процесса, который должен выполняться на стороне сервера.

В клиентских библиотеках Java для Azure существует соглашение о том, что все длительные операции начинаются с begin префикса. Этот префикс указывает, что эта операция является длительной, и что средства взаимодействия с этой операцией немного отличаются от обычного потока запросов и ответа. Наряду с префиксом begin, возвращаемый тип операции также отличается от обычного, чтобы обеспечить полную функциональность длительных операций. Как и в большинстве случаев в пакете SDK Azure для Java, существуют синхронные и асинхронные API для длительных операций:

  • В синхронных клиентах длительные операции возвращают SyncPoller экземпляр.
  • В асинхронных клиентах длительные операции возвращают PollerFlux экземпляр.

Оба SyncPoller и PollerFlux являются абстракциями на стороне клиента, предназначенными для упрощения взаимодействия с длительными операциями на стороне сервера. Остальная часть этой статьи описывает рекомендации при работе с этими типами.

Синхронные длительные операции

Вызов любого API, возвращающего объект SyncPoller , немедленно запустит долго выполняющуюся операцию. API возвращает SyncPoller немедленно, позволяя отслеживать ход выполнения длительной операции и получать окончательный результат. В следующем примере показано, как отслеживать ход выполнения длительной операции с помощью .SyncPoller

SyncPoller<UploadBlobProgress, UploadedBlobProperties> poller = syncClient.beginUploadFromUri(<URI to upload from>)
PollResponse<UploadBlobProgress> response;

do {
    response = poller.poll();
    System.out.println("Status of long running upload operation: " + response.getStatus());
    Duration pollInterval = response.getRetryAfter();
    TimeUnit.MILLISECONDS.sleep(pollInterval.toMillis());
} while (!response.getStatus().isComplete());

В этом примере используется следующий метод на poll() для получения сведений о ходе выполнения длительной операции на SyncPoller. Этот код выводит состояние в консоль, но более эффективная реализация будет принимать соответствующие решения на основе этого состояния.

Метод getRetryAfter() возвращает сведения о том, как долго ждать до следующего опроса. Большинство длительных операций Azure возвращают задержку опроса как часть своего HTTP-ответа (то есть часто используемого заголовка retry-after). Если ответ не содержит задержки опроса, метод getRetryAfter() возвращает длительность, заданную при вызове длительной операции.

В примере выше используется цикл do..while для многократного опроса до завершения операции с длительным временем выполнения. Если вы не заинтересованы в этих промежуточных результатах, можно вместо этого вызвать waitForCompletion(). Этот вызов блокирует текущий поток до завершения длительной операции и возвращает последний ответ опроса:

PollResponse<UploadBlobProgress> response = poller.waitForCompletion();

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

if (LongRunningOperationStatus.SUCCESSFULLY_COMPLETED == response.getStatus()) {
    UploadedBlobProperties result = poller.getFinalResult();
}

Другие полезные API SyncPoller включают:

  1. waitForCompletion(Duration): дождитесь завершения длительной операции в указанный таймаут.
  2. waitUntil(LongRunningOperationStatus): дождитесь получения состояния указанной долгосрочной операции.
  3. waitUntil(LongRunningOperationStatus, Duration): дождитесь, пока будет получен статус указанной длительной операции, или до истечения указанного времени ожидания.

Асинхронные длительные операции

Пример ниже показывает, как PollerFlux позволяет наблюдать за длительной операцией. В асинхронных API сетевые вызовы выполняются в другом потоке, отличном от основного потока, вызывающего subscribe(). Это означает, что основной поток может завершиться до того, как результат будет доступен. Ваша ответственность - убедиться, что приложение не завершает работу до завершения асинхронной операции.

Асинхронный API возвращает PollerFlux немедленно, но сама длительная операция не начнется до подписки на PollerFlux. Этот процесс объясняет, как работают все API, основанные на Flux. В следующем примере показана асинхронная длительно выполняющаяся операция.

asyncClient.beginUploadFromUri(...)
    .subscribe(response -> System.out.println("Status of long running upload operation: " + response.getStatus()));

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

Если вы не хотите получать промежуточные обновления состояния и просто хотите получать уведомления о конечном результате, когда он будет доступен, можно использовать код, аналогичный следующему примеру, например:

asyncClient.beginUploadFromUri(...)
    .last()
    .flatMap(response -> {
        if (LongRunningOperationStatus.SUCCESSFULLY_COMPLETED == response.getStatus()) {
            return response.getFinalResult();
        }
        return Mono.error(new IllegalStateException("Polling completed unsuccessfully with status: "+ response.getStatus()));
    })
    .subscribe(
        finalResult -> processFormPages(finalResult),
        ex -> countDownLatch.countDown(),
        () -> countDownLatch.countDown());

В этом коде вы получите окончательный результат длительной операции путем вызова last(). Этот вызов сообщает PollerFlux, что вы хотите дождаться завершения всех опросов, в этот момент длительная операция достигнет конечного состояния, и вы сможете проверить ее статус, чтобы определить результат. Если опрашиватель указывает на успешное завершение длительной операции, вы можете получить окончательный результат и передать его потребителю в вызове подписки.

Дальнейшие шаги

Теперь, когда вы знакомы с длинными API в Azure SDK для Java, см. статью "Настройка прокси-серверов в пакете SDK Azure для Java", чтобы узнать, как настроить HTTP-клиент дальше.