瞭解如何設定長時間執行作業的輪詢政策。Rust 的Google Cloud 用戶端程式庫提供輔助函式,可簡化長時間執行的作業 (LRO) 的進度監控作業。這些輔助程式會使用政策設定輪詢頻率,並判斷哪些輪詢錯誤是暫時性錯誤 (可安全地重試),哪些是無法復原的錯誤。
有兩項政策可控管 LRO 迴圈的行為:
- 輪詢輪詢政策會控管迴圈等待時間,之後輪詢仍在進行中的 LRO 狀態。
- 輪詢錯誤政策可控制輪詢錯誤時的處理方式。部分輪詢錯誤無法復原,表示作業已中止,或呼叫者沒有權限檢查 LRO 的狀態。其他輪詢錯誤是暫時性的,表示用戶端網路或服務發生暫時性問題。
您可以分別設定這些政策。此外,您也可以對用戶端啟動的所有 LRO 套用政策,或變更單一要求的政策。
必要條件
本指南使用 Cloud Storage 服務,讓程式碼片段更具體,但同樣的概念也適用於使用 LRO 的任何其他服務。
使用本指南前,請先按照「搭配 Rust 使用 Cloud Storage」一文的說明,啟用並驗證 Cloud Storage API。
如需 Rust 程式庫的完整設定說明,請參閱「設定開發環境」。
依附元件
在 Cargo.toml 檔案中新增下列依附元件:
cargo add google-cloud-storage google-cloud-lro
在用戶端中設定所有要求的輪詢頻率
如果您打算對大部分要求使用相同的輪詢退避政策,請考慮將該政策設為用戶端選項。這個程式碼範例會設定所有 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 毫秒,然後在第二次嘗試後等待 500 毫秒。後續嘗試會等待 1 秒、2 秒、4 秒和 8 秒,之後每次嘗試都會等待 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。如果您打算對同一用戶端的大部分要求使用相同的輪詢政策,請考慮將該政策設為用戶端選項。
這個程式碼範例會為所有 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?;