איך מגדירים מדיניות דגימה לפעולות ממושכותGoogle Cloud ספריות הלקוח של Rust מספקות פונקציות עזר כדי לפשט את מעקב ההתקדמות של פעולות ארוכות טווח (LRO). הכלים האלה משתמשים במדיניות כדי להגדיר את תדירות הבדיקה ולקבוע אילו שגיאות בבדיקה הן זמניות (ואפשר לנסות שוב לפתור אותן) ואילו שגיאות הן בלתי הפיכות.
שני כללי מדיניות קובעים את ההתנהגות של לולאות LRO:
- מדיניות ההשהיה לפני ניסיון חוזר של דגימה קובעת כמה זמן יחכו הלולאות לפני בדיקת הסטטוס של פעולה ארוכת טווח שעדיין מתבצעת.
- המדיניות בנושא שגיאות בסקרים קובעת מה לעשות במקרה של שגיאה בסקר. חלק משגיאות הסקר לא ניתנות לתיקון ומצביעות על כך שהפעולה בוטלה או שלמתקשר אין הרשאות לבדוק את הסטטוס של ה-LRO. שגיאות אחרות של שליחת בקשות הן חולפות ומעידות על בעיה זמנית ברשת של הלקוח או בשירות.
אפשר להגדיר כל אחת מהמדיניות האלה בנפרד. בנוסף, אפשר להחיל מדיניות על כל הפעולות הממושכות שהופעלו בלקוח, או לשנות את המדיניות לבקשה יחידה.
דרישות מוקדמות
במדריך הזה נעשה שימוש בשירות Cloud Storage כדי להציג את קטעי הקוד בצורה קונקרטית, אבל אותם מושגים רלוונטיים לכל שירות אחר שמשתמש ב-LRO.
לפני שמשתמשים במדריך הזה, צריך לפעול לפי ההוראות במאמר שימוש ב-Cloud Storage עם Rust כדי להפעיל את Cloud Storage API ולאמת אותו.
הוראות מלאות להגדרת ספריות Rust זמינות במאמר הגדרת סביבת הפיתוח.
תלויות
מוסיפים את יחסי התלות הבאים לקובץ Cargo.toml:
cargo add google-cloud-storage google-cloud-lro
הגדרת תדירות הבדיקה לכל הבקשות בלקוח
אם אתם מתכננים להשתמש באותה מדיניות להשהיית שליחת בקשות (backoff) לרוב הבקשות עם אותו לקוח, כדאי להגדיר את המדיניות כאפשרות לקוח. בדוגמת הקוד הזו מוגדרת תדירות הסקר לכל הבקשות לשירות 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(())
}
אלא אם מבטלים את המדיניות באמצעות הגדרה לכל בקשה, המדיניות נשארת בתוקף לכל פעולה ארוכת טווח שהלקוח מתחיל.
לדוגמה, המדיניות הזו תחול על השיחה הבאה:
let mut operation = client
.rename_folder()
/* more stuff */
.send()
.await?;
בדוגמה הזו, ספריית הלקוח ממתינה 250 אלפיות השנייה אחרי הניסיון הראשון של שליחת בקשת polling, ואז 500 אלפיות השנייה אחרי הניסיון השני. בניסיונות הבאים יש המתנה של שנייה אחת, שתי שניות, ארבע שניות ושמונה שניות, ואז בכל הניסיונות הבאים יש המתנה של 10 שניות.
הגדרת תדירות הבדיקה לבקשה ספציפית
אפשר להגדיר את תדירות הבדיקה של בקשה ספציפית, וכך לבטל מדיניות שהוגדרה ברמת הלקוח. לדוגמה:
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(())
}
הגדרת שגיאות סקר שניתן לנסות שוב לכל הבקשות בלקוח
כדי להגדיר שגיאות שאפשר לנסות שוב, משתמשים בסוג שמטמיע את המאפיין PollingErrorPolicy. ספריות הלקוח מספקות כמה כללי מדיניות. האפשרות השמרנית היא Aip194Strict. אם אתם מתכננים להשתמש באותה מדיניות של שליחת בקשות לשרת (polling) עבור רוב הבקשות עם אותו לקוח, כדאי להגדיר את המדיניות כאפשרות לקוח.
בדוגמת הקוד הזו מוגדרים שגיאות סקר שניתן לנסות שוב עבור כל הבקשות לשירות 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(())
}
מדיניות השגיאות של בדיקת הסטטוס מטפלת בשגיאות במהלך לולאת ההמתנה של LRO, אבל אפשר גם להוסיף מדיניות ניסיון חוזר רגילה כדי לטפל בשגיאות זמניות שעשויות להתרחש כששולחים את הבקשה הראשונית להפעלת LRO:
let client = StorageControl::builder()
.with_retry_policy(
retry_policy::Aip194Strict
.with_attempt_limit(100)
.with_time_limit(Duration::from_secs(300)),
)
.build()
.await?;
אלא אם מבטלים את המדיניות באמצעות הגדרה לכל בקשה, המדיניות הזו ממשיכה לחול על כל פעולה ארוכת טווח שהלקוח מתחיל. לדוגמה, אם מבצעים את השיחה הבאה:
let mut operation = client
.rename_folder()
/* more stuff */
.send()
.await?;
הערה: ספריית הלקוח מתייחסת רק ל-UNAVAILABLE (ראו AIP-194) כשגיאה שאפשר לנסות שוב, ומפסיקה את הבדיקה אחרי 100 ניסיונות או 300 שניות, לפי מה שקורה קודם.
הגדרת שגיאות סקר שניתן לנסות שוב עבור בקשה ספציפית
כדי להגדיר שגיאות סקר שניתן לנסות שוב עבור בקשה ספציפית, צריך להשתמש בסוג שמטמיע את מאפיין PollingErrorPolicy ולהוסיף את מאפיין RequestOptionsBuilder להיקף.
בדוגמת הקוד הזו מוגדרות שגיאות סקר שניתן לנסות שוב עבור בקשה ספציפית לשירות 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(())
}
כדאי גם להוסיף מדיניות ניסיון חוזר, למקרה שהבקשה הראשונית להפעלת ה-LRO תיכשל:
let client = StorageControl::builder()
.with_retry_policy(
retry_policy::Aip194Strict
.with_attempt_limit(100)
.with_time_limit(Duration::from_secs(300)),
)
.build()
.await?;