Configurer les stratégies de nouvelle tentative

Les bibliothèques clientes pour Rust peuvent réessayer automatiquement les Google Cloud opérations qui échouent en raison d'erreurs temporaires. Découvrez comment créer et personnaliser des boucles de nouvelle tentative, implémenter une stratégie de nouvelle tentative commune pour toutes les requêtes et remplacer les stratégies par défaut pour des requêtes spécifiques.

Prérequis

Les exemples de ce guide utilisent le service Secret Manager. Cependant, les mêmes concepts fonctionnent pour d'autres Google Cloud services.

Avant de continuer, suivez la procédure Créer un secret et y accéder à l'aide de Secret Manager pour activer et authentifier l'API Secret Manager.

Dépendances

Après avoir activé Secret Manager, déclarez vos dépendances dans votre fichier Cargo.toml :

cargo add google-cloud-secretmanager-v1

Configurer la stratégie de nouvelle tentative par défaut

Cet exemple utilise la stratégie Aip194Strict. Cette stratégie est basée sur les consignes d'AIP-194, qui décrit les conditions dans lesquelles un client d'API Google doit réessayer automatiquement une requête.

Pour définir la stratégie Aip194Strict comme stratégie par défaut pour un service, définissez la stratégie lors de l'initialisation du client :

   let client = SecretManagerService::builder()
       .with_retry_policy(Aip194Strict)
       .build()
       .await?;

Une fois la stratégie définie, vous pouvez utiliser le service comme d'habitude :

   let mut list = client
       .list_secrets()
       .set_parent(format!("projects/{project_id}"))
       .by_item();
   while let Some(secret) = list.next().await {
       let secret = secret?;
       println!("  secret={}", secret.name);
   }

Configurer la stratégie de nouvelle tentative par défaut : code complet

Cet exemple de code applique la stratégie Aip194Strict au service Secret Manager.

use google_cloud_gax::paginator::ItemPaginator as _;
use google_cloud_gax::retry_policy::Aip194Strict;
use google_cloud_secretmanager_v1::client::SecretManagerService;

pub async fn sample(project_id: &str) -> anyhow::Result<()> {
   let client = SecretManagerService::builder()
       .with_retry_policy(Aip194Strict)
       .build()
       .await?;

   let mut list = client
       .list_secrets()
       .set_parent(format!("projects/{project_id}"))
       .by_item();
   while let Some(secret) = list.next().await {
       let secret = secret?;
       println!("  secret={}", secret.name);
   }

   Ok(())
}

Configurer la stratégie de nouvelle tentative par défaut avec des limites

Par défaut, la stratégie Aip194Strict ne limite pas le nombre de tentatives ni le temps passé à réessayer les requêtes. Toutefois, vous pouvez ajouter des limites à la stratégie.

Par exemple, vous pouvez limiter à la fois le nombre de tentatives et le temps passé dans la boucle de nouvelle tentative :

   let client = SecretManagerService::builder()
       .with_retry_policy(
           Aip194Strict
               .with_attempt_limit(5)
               .with_time_limit(Duration::from_secs(15)),
       )
       .build()
       .await?;

Avec cette configuration, les requêtes fonctionneront comme d'habitude :

   let mut list = client
       .list_secrets()
       .set_parent(format!("projects/{project_id}"))
       .by_item();
   while let Some(secret) = list.next().await {
       let secret = secret?;
       println!("  secret={}", secret.name);
   }

Configurer la stratégie de nouvelle tentative par défaut avec des limites : code complet

Cet exemple de code applique la stratégie Aip194Strict au service Secret Manager avec une limite de tentatives et une limite de temps personnalisées.

use google_cloud_gax::paginator::ItemPaginator as _;
use google_cloud_gax::retry_policy::Aip194Strict;
use google_cloud_gax::retry_policy::RetryPolicyExt;
use google_cloud_secretmanager_v1::client::SecretManagerService;
use std::time::Duration;


pub async fn sample(project_id: &str) -> anyhow::Result<()> {
   let client = SecretManagerService::builder()
       .with_retry_policy(
           Aip194Strict
               .with_attempt_limit(5)
               .with_time_limit(Duration::from_secs(15)),
       )
       .build()
       .await?;


   let mut list = client
       .list_secrets()
       .set_parent(format!("projects/{project_id}"))
       .by_item();
   while let Some(secret) = list.next().await {
       let secret = secret?;
       println!("  secret={}", secret.name);
   }


   Ok(())
}

Remplacer la stratégie de nouvelle tentative pour une requête

Parfois, les applications doivent remplacer la stratégie de nouvelle tentative pour une requête spécifique. Par exemple, le développeur d'applications peut connaître des détails spécifiques du service ou de l'application et déterminer qu'il est sûr de tolérer davantage d'erreurs.

Par exemple, la suppression d'un secret est idempotente, car elle ne peut réussir qu'une seule fois. Toutefois, la bibliothèque cliente suppose que toutes les opérations de suppression ne sont pas sûres. Vous pouvez remplacer la stratégie pour une requête :

   client
       .delete_secret()
       .set_name(format!("projects/{project_id}/secrets/{secret_id}"))
       .with_retry_policy(
           AlwaysRetry
               .with_attempt_limit(5)
               .with_time_limit(Duration::from_secs(15)),
       )
       .send()
       .await?;

Remplacer la stratégie de nouvelle tentative pour une requête : code complet

Cet exemple de code remplace la limite de tentatives et la limite de temps pour une requête spécifique adressée au service Secret Manager.

use google_cloud_gax::options::RequestOptionsBuilder;
use google_cloud_gax::retry_policy::AlwaysRetry;
use google_cloud_gax::retry_policy::RetryPolicyExt;
use google_cloud_secretmanager_v1::client::SecretManagerService;
use std::time::Duration;


pub async fn sample(
   client: &SecretManagerService,
   project_id: &str,
   secret_id: &str,
) -> anyhow::Result<()> {
   client
       .delete_secret()
       .set_name(format!("projects/{project_id}/secrets/{secret_id}"))
       .with_retry_policy(
           AlwaysRetry
               .with_attempt_limit(5)
               .with_time_limit(Duration::from_secs(15)),
       )
       .send()
       .await?;


   Ok(())
}