Saiba como configurar políticas de pesquisa para operações de longa duração. As Google Cloud bibliotecas de cliente para Rust fornecem funções auxiliares para simplificar o monitoramento do progresso de operações de longa duração (LROs, na sigla em inglês). Esses auxiliares usam políticas para configurar a frequência de pesquisa e determinar quais erros de pesquisa são temporários (e podem ser repetidos com segurança) e quais são irrecuperáveis.
Duas políticas controlam o comportamento dos loops de LRO:
- A política de espera de pesquisa controla por quanto tempo os loops aguardam antes de pesquisar o status de uma LRO que ainda está em andamento.
- A política de erro de pesquisa controla o que fazer em caso de erro de pesquisa. Alguns erros de pesquisa são irrecuperáveis e indicam que a operação foi interrompida ou que o autor da chamada não tem permissões para verificar o status da LRO. Outros erros de pesquisa são temporários e indicam um problema temporário na rede do cliente ou no serviço.
É possível definir cada uma dessas políticas de forma independente. Além disso, você pode aplicar uma política a todas as LROs iniciadas em um cliente ou mudar a política de uma única solicitação.
Pré-requisitos
Este guia usa o serviço do Cloud Storage para manter os snippets de código concretos, mas os mesmos conceitos se aplicam a qualquer outro serviço que use LROs.
Antes de usar este guia, siga as instruções em Como usar o Cloud Storage com Rust para ativar e autenticar a API Cloud Storage.
Para instruções completas de configuração das bibliotecas Rust, consulte Como configurar o ambiente de desenvolvimento.
Dependências
Adicione as seguintes dependências ao arquivo Cargo.toml:
cargo add google-cloud-storage google-cloud-lro
Configurar a frequência de pesquisa para todas as solicitações em um cliente
Se você planeja usar a mesma política de espera de pesquisa para a maioria das solicitações com o mesmo cliente, defina a política como uma opção de cliente. Este exemplo de código configura a frequência de pesquisa para todas as solicitações ao serviço do Cloud Storage.
pub async fn client_backoff(bucket: &str, folder: &str, dest: &str) -> Result<()> {
// Use a type that implements the `PollingBackoffPolicy` trait, in this case
// `ExponentialBackoffBuilder`.
use google_cloud_gax::exponential_backoff::ExponentialBackoffBuilder;
use google_cloud_lro::Poller;
use std::time::Duration;
let client = StorageControl::builder()
// Initialize the policy with a chosen delay duration.
.with_polling_backoff_policy(
ExponentialBackoffBuilder::new()
.with_initial_delay(Duration::from_millis(250))
.with_maximum_delay(Duration::from_secs(10))
.build()?,
)
.build()
.await?;
// Initiate an LRO using polling.
let response = client
.rename_folder()
.set_name(format!("projects/_/buckets/{bucket}/folders/{folder}"))
.set_destination_folder_id(dest)
.poller()
.until_done()
.await?;
println!("LRO completed, response={response:?}");
Ok(())
}
A menos que você substitua a política por uma configuração por solicitação, ela permanecerá em vigor para qualquer operação de longa duração iniciada pelo cliente.
Por exemplo, a chamada a seguir usará essa política:
let mut operation = client
.rename_folder()
/* more stuff */
.send()
.await?;
Neste exemplo de chamada, a biblioteca de cliente aguarda 250 ms após a primeira tentativa de pesquisa e, em seguida, 500 ms para a segunda tentativa. As tentativas subsequentes aguardam 1 s, 2 s, 4 s e 8 s, e todas as tentativas futuras aguardam 10 s.
Configurar a frequência de pesquisa para uma solicitação específica
É possível configurar a frequência de pesquisa para uma solicitação individual, que substitui qualquer política definida no nível do cliente. Exemplo:
pub async fn rpc_backoff(bucket: &str, folder: &str, dest: &str) -> Result<()> {
// Use a type that implements the `PollingBackoffPolicy` trait, in this case
// `ExponentialBackoffBuilder`.
use google_cloud_gax::exponential_backoff::ExponentialBackoffBuilder;
use std::time::Duration;
// To configure the request, bring the RequestOptionsBuilder trait into
// scope.
use google_cloud_gax::options::RequestOptionsBuilder;
use google_cloud_lro::Poller;
let client = StorageControl::builder().build().await?;
// Create the request builder.
let response = client
.rename_folder()
// Configure the polling backoff policy.
.with_polling_backoff_policy(
ExponentialBackoffBuilder::new()
.with_initial_delay(Duration::from_millis(250))
.with_maximum_delay(Duration::from_secs(10))
.build()?,
)
.set_name(format!("projects/_/buckets/{bucket}/folders/{folder}"))
.set_destination_folder_id(dest)
// Issue the polling request as normal.
.poller()
.until_done()
.await?;
println!("LRO completed, response={response:?}");
Ok(())
}
Configurar erros de pesquisa repetíveis para todas as solicitações em um cliente
Para configurar erros repetíveis, use um tipo que implemente a característica PollingErrorPolicy. As bibliotecas de cliente fornecem várias políticas. Uma opção conservadora é Aip194Strict. Se você planeja usar a mesma política de pesquisa para a maioria das solicitações com o mesmo cliente, defina a política como uma opção de cliente.
Este exemplo de código configura os erros de pesquisa repetíveis para todas as solicitações ao serviço do Cloud Storage:
pub async fn client_error_policy(bucket: &str, folder: &str, dest: &str) -> Result<()> {
// Use a type that implements the `PollingErrorPolicy` trait, in this case
// `Aip194Strict`.
use google_cloud_gax::polling_error_policy::Aip194Strict;
use google_cloud_gax::polling_error_policy::PollingErrorPolicyExt;
use google_cloud_lro::Poller;
use std::time::Duration;
// Add the polling policy that you want to use for all long-running
// operations.
let client = StorageControl::builder()
.with_polling_error_policy(
Aip194Strict
.with_attempt_limit(100)
.with_time_limit(Duration::from_secs(300)),
)
.build()
.await?;
// Initiate an LRO using polling.
let response = client
.rename_folder()
.set_name(format!("projects/_/buckets/{bucket}/folders/{folder}"))
.set_destination_folder_id(dest)
.poller()
.until_done()
.await?;
println!("LRO completed, response={response:?}");
Ok(())
}
Embora a política de erro de pesquisa processe erros durante o loop de espera da LRO, também é possível adicionar uma política de repetição padrão para processar erros temporários que podem ocorrer ao enviar inicialmente a solicitação para iniciar a LRO:
let client = StorageControl::builder()
.with_retry_policy(
retry_policy::Aip194Strict
.with_attempt_limit(100)
.with_time_limit(Duration::from_secs(300)),
)
.build()
.await?;
A menos que você substitua a política por uma configuração por solicitação, ela permanecerá em vigor para qualquer operação de longa duração iniciada pelo cliente. Por exemplo, se você fizer a seguinte chamada:
let mut operation = client
.rename_folder()
/* more stuff */
.send()
.await?;
Observação: a biblioteca de cliente trata apenas UNAVAILABLE (consulte AIP-194) como um
erro repetível e interrompe a pesquisa após 100 tentativas ou 300 segundos, o que
ocorrer primeiro.
Configurar erros de pesquisa repetíveis para uma solicitação específica
É possível configurar erros de pesquisa repetíveis para uma solicitação específica usando um tipo que implementa a característica PollingErrorPolicy e trazendo a característica RequestOptionsBuilder para o escopo.
Este exemplo de código configura erros de pesquisa repetíveis para uma solicitação específica ao serviço do Cloud Storage.
pub async fn rpc_error_policy(bucket: &str, folder: &str, dest: &str) -> Result<()> {
// Use a type that implements the `PollingErrorPolicy` trait, in this case
// `Aip194Strict`.
use google_cloud_gax::polling_error_policy::Aip194Strict;
use google_cloud_gax::polling_error_policy::PollingErrorPolicyExt;
// Bring `RequestOptionsBuilder` into scope.
use google_cloud_gax::options::RequestOptionsBuilder;
use std::time::Duration;
use google_cloud_lro::Poller;
let client = StorageControl::builder().build().await?;
// Create the request builder.
let response = client
.rename_folder()
// Configure the polling error policy.
.with_polling_error_policy(
Aip194Strict
.with_attempt_limit(100)
.with_time_limit(Duration::from_secs(300)),
)
.set_name(format!("projects/_/buckets/{bucket}/folders/{folder}"))
.set_destination_folder_id(dest)
// Initialize the request.
.poller()
.until_done()
.await?;
println!("LRO completed, response={response:?}");
Ok(())
}
Também é possível adicionar uma política de repetição, caso a solicitação inicial para iniciar a LRO falhe:
let client = StorageControl::builder()
.with_retry_policy(
retry_policy::Aip194Strict
.with_attempt_limit(100)
.with_time_limit(Duration::from_secs(300)),
)
.build()
.await?;