redis_cloud/
tasks.rs

1//! Asynchronous task tracking and management
2//!
3//! This module provides functionality for tracking long-running operations in
4//! Redis Cloud. Many API operations are asynchronous and return a task ID that
5//! can be used to monitor progress and completion status.
6//!
7//! # Overview
8//!
9//! Redis Cloud uses tasks for operations that may take time to complete, such as:
10//! - Creating or deleting subscriptions
11//! - Database creation, updates, and deletion
12//! - Backup and restore operations
13//! - Import/export operations
14//! - Network configuration changes
15//!
16//! # Task Lifecycle
17//!
18//! 1. **Initiated**: Task is created and queued
19//! 2. **Processing**: Task is being executed
20//! 3. **Completed**: Task finished successfully
21//! 4. **Failed**: Task encountered an error
22//!
23//! # Key Features
24//!
25//! - **Task Status**: Check current status of any task
26//! - **Progress Tracking**: Monitor completion percentage for long operations
27//! - **Result Retrieval**: Get operation results once completed
28//! - **Error Information**: Access detailed error messages for failed tasks
29//! - **Task History**: Query historical task information
30//!
31//! # Example Usage
32//!
33//! ```no_run
34//! use redis_cloud::{CloudClient, TaskHandler};
35//!
36//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
37//! let client = CloudClient::builder()
38//!     .api_key("your-api-key")
39//!     .api_secret("your-api-secret")
40//!     .build()?;
41//!
42//! let handler = TaskHandler::new(client);
43//!
44//! // Get task status
45//! let task = handler.get_task_by_id("task-123".to_string()).await?;
46//!
47//! // Check if task is complete
48//! if task.status == Some("completed".to_string()) {
49//!     println!("Task completed successfully");
50//!     if let Some(response) = task.response {
51//!         println!("Result: {:?}", response);
52//!     }
53//! }
54//! # Ok(())
55//! # }
56//! ```
57
58use crate::{CloudClient, Result};
59use serde::{Deserialize, Serialize};
60use serde_json::Value;
61use std::collections::HashMap;
62
63// ============================================================================
64// Models
65// ============================================================================
66
67/// ProcessorResponse
68#[derive(Debug, Clone, Serialize, Deserialize)]
69#[serde(rename_all = "camelCase")]
70pub struct ProcessorResponse {
71    #[serde(skip_serializing_if = "Option::is_none")]
72    pub resource_id: Option<i32>,
73
74    #[serde(skip_serializing_if = "Option::is_none")]
75    pub additional_resource_id: Option<i32>,
76
77    #[serde(skip_serializing_if = "Option::is_none")]
78    pub resource: Option<HashMap<String, Value>>,
79
80    #[serde(skip_serializing_if = "Option::is_none")]
81    pub error: Option<String>,
82
83    #[serde(skip_serializing_if = "Option::is_none")]
84    pub additional_info: Option<String>,
85
86    /// Additional fields from the API
87    #[serde(flatten)]
88    pub extra: Value,
89}
90
91/// TaskStateUpdate
92#[derive(Debug, Clone, Serialize, Deserialize)]
93#[serde(rename_all = "camelCase")]
94pub struct TaskStateUpdate {
95    #[serde(skip_serializing_if = "Option::is_none")]
96    pub task_id: Option<String>,
97
98    #[serde(skip_serializing_if = "Option::is_none")]
99    pub command_type: Option<String>,
100
101    #[serde(skip_serializing_if = "Option::is_none")]
102    pub status: Option<String>,
103
104    #[serde(skip_serializing_if = "Option::is_none")]
105    pub description: Option<String>,
106
107    #[serde(skip_serializing_if = "Option::is_none")]
108    pub timestamp: Option<String>,
109
110    #[serde(skip_serializing_if = "Option::is_none")]
111    pub response: Option<ProcessorResponse>,
112
113    /// HATEOAS links
114    #[serde(skip_serializing_if = "Option::is_none")]
115    pub links: Option<Vec<HashMap<String, Value>>>,
116
117    /// Additional fields from the API
118    #[serde(flatten)]
119    pub extra: Value,
120}
121
122// ============================================================================
123// Handler
124// ============================================================================
125
126/// Handler for asynchronous task operations
127///
128/// Tracks and manages long-running operations, providing status updates,
129/// progress monitoring, and result retrieval for asynchronous API calls.
130pub struct TasksHandler {
131    client: CloudClient,
132}
133
134impl TasksHandler {
135    /// Create a new handler
136    pub fn new(client: CloudClient) -> Self {
137        Self { client }
138    }
139
140    /// Get tasks
141    /// Gets a list of all currently running tasks for this account.
142    ///
143    /// GET /tasks
144    pub async fn get_all_tasks(&self) -> Result<()> {
145        self.client.get("/tasks").await
146    }
147
148    /// Get a single task
149    /// Gets details and status of a single task by the Task ID.
150    ///
151    /// GET /tasks/{taskId}
152    pub async fn get_task_by_id(&self, task_id: String) -> Result<TaskStateUpdate> {
153        self.client.get(&format!("/tasks/{}", task_id)).await
154    }
155}