async_dashscope/operation/
task.rs1use crate::error::{DashScopeError, Result};
2use crate::{Client, operation::common::TaskStatus};
3use output::*;
4use std::time::Duration;
5use tokio::time::sleep;
6const TASK_PATH: &str = "/tasks";
7
8pub mod output;
9
10pub struct Task<'a> {
11 client: &'a Client,
12}
13
14impl<'a> Task<'a> {
15 pub fn new(client: &'a Client) -> Self {
16 Self { client }
17 }
18
19 pub(crate) async fn query(&self, task_id: &str) -> Result<TaskResult> {
20 let http_client = self.client.http_client();
21 let headers = self.client.config().headers();
22 let req = http_client
23 .get(
24 self.client
25 .config()
26 .url(format!("{}/{}", TASK_PATH, task_id).as_str()),
27 )
28 .headers(headers)
29 .build()?;
30
31 let resp = http_client.execute(req).await?.bytes().await?;
32
33 if resp.is_empty() {
35 return Err(DashScopeError::ApiError(crate::error::ApiError {
36 message: "API returned empty response".to_string(),
37 request_id: None,
38 code: Some("EmptyResponse".to_string()),
39 }));
40 }
41
42 let raw_response_str = String::from_utf8_lossy(resp.as_ref());
43 println!("Raw API response: {}", raw_response_str);
44
45 let resp_json = serde_json::from_slice::<TaskResult>(resp.as_ref()).map_err(|e| {
46 crate::error::DashScopeError::JSONDeserialize {
47 source: e,
48 raw_response: String::from_utf8_lossy(&resp).to_string(),
49 }
50 })?;
51
52 Ok(resp_json)
53 }
54
55 pub async fn poll_task_status(
76 &self,
77 task_id: &str,
78 interval: u64,
79 max_attempts: u32,
80 ) -> Result<TaskResult> {
81 for attempt in 1..=max_attempts {
82 match self.query(task_id).await {
85 Ok(result) => {
86 let task_status = &result.output.task_status;
87 match task_status {
91 TaskStatus::Succeeded => {
92 return Ok(result);
94 }
95 TaskStatus::Failed => {
96 return Ok(result);
98 }
99 TaskStatus::Pending | TaskStatus::Running => {
100 println!("任务仍在进行中,等待 {} 秒后继续轮询...", interval);
102 sleep(Duration::from_secs(interval)).await;
103 }
104 TaskStatus::Canceled | TaskStatus::Unknown => {
105 return Ok(result);
106 }
107 }
108 }
109 Err(e) => {
110 match &e {
112 DashScopeError::JSONDeserialize {
113 source: _,
114 raw_response: _,
115 } => {
116 sleep(Duration::from_secs(interval)).await;
119 }
120 DashScopeError::Reqwest(_) => {
121 sleep(Duration::from_secs(interval)).await;
123 }
124 DashScopeError::ApiError(api_error) => {
125 if api_error.code.as_deref() == Some("EmptyResponse") {
127 sleep(Duration::from_secs(interval)).await;
128 } else {
129 return Err(e);
131 }
132 }
133 _ => {
134 return Err(e);
136 }
137 }
138 }
139 }
140 if attempt > max_attempts {
141 break;
142 }
143 }
144
145 Err(DashScopeError::TimeoutError(
147 "轮询超时,任务未在预期时间内完成".to_string(),
148 ))
149 }
150}