Some Google Cloud API methods take a significant amount of time to complete.
Instead of blocking until the work finishes, these methods return an
Operation resource that represents an in-progress operation so
that your application can poll for its status and final result.
The Cloud Client Libraries for Rust provide helpers for working with these long-running operations (LROs). This document shows you how to start an LRO, poll automatically until completion, inspect intermediate progress updates, and poll manually.
Before you begin
This document uses Cloud Storage to keep the code examples concrete, though the same concepts apply to any Google Cloud service that uses LROs.
Before running the code in this document, complete the following prerequisites:
- Create or select a Google Cloud project with billing enabled.
- Follow Get started with Rust to set up your development environment and credentials.
- Create a Cloud Storage bucket with
hierarchical namespace enabled, create a source folder to
rename, and grant your principal an Identity and Access Management (IAM) role with
permission to manage folders, such as Storage Admin (
roles/storage.admin).
Dependencies
Add the client library and LRO crates to your Cargo.toml file:
cargo add google-cloud-storage google-cloud-lro google-cloud-longrunning anyhow
Add tokio for asynchronous execution and timers:
cargo add tokio --features full
Start a long-running operation
The examples in this document call the Cloud Storage
rename folder operation, which returns an LRO. To start an LRO
directly and obtain the initial Operation resource, complete the following
steps:
Add
usedeclarations to shorten type paths:Define an
asyncfunction that accepts the bucket ID, source folder ID, and destination folder ID:Initialize the
StorageControlclient:Create the
rename_folderrequest builder:Send the request and await the initial
Operationresource, which represents the background operation:
After starting the operation, wait for it to finish to retrieve its final outcome.
Automatically poll a long-running operation
For most use cases, use the Poller trait's until_done method instead of
calling send directly. The poller starts the LRO, polls according to the
client's backoff and error policies, and resolves to the final response:
Bring the
Pollertrait into scope:Initialize a
StorageControlclient and configure therename_folderrequest builder:Call
polleranduntil_doneon the request builder to await completion and print the result:
Complete automatic polling code
The following function shows the complete automatic polling example:
Poll a long-running operation with intermediate results
The until_done method returns only the final outcome and omits intermediate
metadata updates. If your application needs progress updates while the LRO
runs, obtain a poller with poller and call poll in a loop:
Import
PollerandPollingResult:Convert the request builder into a poller using
poller:Call
poller.poll().awaitin a loop to processInProgress,PollingError, andCompletedstates:
When calling poll directly, your loop controls the delay between polling
attempts. Choose a delay suited to the expected duration of the operation.
Complete code for polling with intermediate results
The following function shows the complete poll loop:
Manually poll a long-running operation
Although the Poller trait handles almost all use cases, you can also poll an
Operation manually using get_operation:
After starting the LRO with
send, enter a loop and check thedonefield:Inspect
operation.result. Theresultfield is anOptionbecause some operations, such as deletions, finish without returning a payload. Forrename_folder, the service returns aFolderresource:Check whether the operation finished with an error. The error variant contains a
Statusmessage that the following example formats into an error, or that you can convert to a client error usingError::service:If the operation succeeded, unpack the
Anypayload into the expectedFolderresponse type:Add a wildcard arm because enums in the Cloud Client Libraries for Rust are marked
#[non_exhaustive]:Optional: While
operation.doneisfalse, unpackoperation.metadatato inspect progress updates:Wait before polling again. This example sleeps for a fixed 500 ms for brevity; in production code, use truncated exponential backoff:
Call
get_operationwithoperation.nameto refresh the operation status:
Complete manual polling code
The following function combines all of the manual polling steps: