Como configurar políticas de pesquisa

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?;