Configurazione delle policy di polling

Scopri come configurare i criteri di polling per le operazioni a lunga esecuzione. Le librerie client Google Cloud per Rust forniscono funzioni helper per semplificare il monitoraggio dello stato di avanzamento delle operazioni a lunga esecuzione (LRO). Questi helper utilizzano le policy per configurare la frequenza di polling e determinare quali errori di polling sono temporanei (e possono essere riprovati in sicurezza) e quali sono irrecuperabili.

Due criteri controllano il comportamento dei loop LRO:

  • Il polling backoff policy controlla per quanto tempo i loop attendono prima di eseguire il polling dello stato di un'operazione LRO ancora in corso.
  • Le norme sugli errori di polling controllano cosa fare in caso di errore di polling. Alcuni errori di polling sono irrecuperabili e indicano che l'operazione è stata interrotta o che il chiamante non dispone delle autorizzazioni per controllare lo stato dell'operazione di lunga durata. Altri errori di polling sono temporanei e indicano un problema temporaneo nella rete client o nel servizio.

Puoi impostare ciascuna di queste policy in modo indipendente. Inoltre, puoi applicare un criterio a tutte le operazioni di lunga durata avviate su un client o modificare il criterio per una singola richiesta.

Prerequisiti

Questa guida utilizza il servizio Cloud Storage per mantenere concreti gli snippet di codice, ma gli stessi concetti si applicano a qualsiasi altro servizio che utilizza operazioni a lunga esecuzione.

Prima di utilizzare questa guida, segui la procedura descritta in Utilizzo di Cloud Storage con Rust per abilitare e autenticare l'API Cloud Storage.

Per istruzioni di configurazione complete per le librerie Rust, vedi Configurazione dell'ambiente di sviluppo.

Dipendenze

Aggiungi le seguenti dipendenze al file Cargo.toml:

cargo add google-cloud-storage google-cloud-lro

Configurare la frequenza di polling per tutte le richieste in un client

Se prevedi di utilizzare la stessa strategia di backoff per la maggior parte delle richieste con lo stesso client, valuta la possibilità di impostarla come opzione client. Questo esempio di codice configura la frequenza di polling per tutte le richieste al servizio 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 meno che tu non esegua l'override della policy con un'impostazione per richiesta, la policy rimane in vigore per qualsiasioperazione a lunga esecuzionea avviata dal client.

Ad esempio, la seguente chiamata utilizzerà questa norma:

    let mut operation = client
        .rename_folder()
        /* more stuff */
        .send()
        .await?;

In questa chiamata di esempio, la libreria client attende 250 ms dopo il primo tentativo di polling, quindi 500 ms per il secondo tentativo. I tentativi successivi attendono 1 s, 2 s, 4 s e 8 s, mentre tutti i tentativi successivi attendono 10 s.

Configura la frequenza di polling per una richiesta specifica

Puoi configurare la frequenza di polling per una singola richiesta, che override qualsiasi policy impostata a livello di client. Ad esempio:

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(())
}

Configura gli errori di polling ripetibili per tutte le richieste in un client

Per configurare gli errori ripetibili, utilizza un tipo che implementa il trait PollingErrorPolicy. Le librerie client forniscono diverse norme; una scelta conservativa è Aip194Strict. Se prevedi di utilizzare la stessa norma di polling per la maggior parte delle richieste con lo stesso client, valuta la possibilità di impostarla come opzione client.

Questo esempio di codice configura gli errori di polling ripetibili per tutte le richieste al servizio 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(())
}

Mentre la policy di errore di polling gestisce gli errori durante il ciclo di attesa LRO, puoi anche aggiungere una policy di ripetizione standard per gestire gli errori temporanei che potrebbero verificarsi quando invii inizialmente la richiesta per avviare l'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 meno che non esegui l'override del criterio con un'impostazione per richiesta, questo criterio rimane in vigore per qualsiasioperazione a lunga esecuzionea avviata dal client. Ad esempio, se esegui la seguente chiamata:

    let mut operation = client
        .rename_folder()
        /* more stuff */
        .send()
        .await?;

Nota:la libreria client considera solo UNAVAILABLE (vedi AIP-194) come un errore ripetibile e interrompe il polling dopo 100 tentativi o 300 secondi, a seconda di quale si verifica per primo.

Configura gli errori di polling ripetibili per una richiesta specifica

Puoi configurare gli errori di polling ripetibili per una richiesta specifica utilizzando un tipo che implementa il tratto PollingErrorPolicy e portando il tratto RequestOptionsBuilder nell'ambito.

Questo esempio di codice configura gli errori di polling ripetibili per una richiesta specifica al servizio 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(())
}

Potresti anche prendere in considerazione l'aggiunta di una policy di nuovi tentativi nel caso in cui la richiesta iniziale di avvio dell'operazione di lunga durata non vada a buon fine:

    let client = StorageControl::builder()
        .with_retry_policy(
            retry_policy::Aip194Strict
                .with_attempt_limit(100)
                .with_time_limit(Duration::from_secs(300)),
        )
        .build()
        .await?;