surf::getでタイムアウトを設定する
環境
- cargo 1.47.0
- surf 2.1.0
- async-std 1.7.0
方法
async_std::future::timeout関数を使うとハッピーになれる。
以下は5秒以内にレスポンスが無ければタイムアウトするコード。
use std::error::Error; use std::fmt; use std::time::Duration; #[derive(Debug)] struct MyError(String); impl Error for MyError {} impl fmt::Display for MyError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.0) } } /// urlにgetリクエストする。 /// ステータスコードとbodyを返す。 async fn get(url: &str) -> Result<(surf::StatusCode, String), Box<dyn Error>> { match surf::get(url).await { Ok(ref mut res) => Ok((res.status(), res.body_string().await?)), Err(e) => Err(Box::new(MyError(e.to_string()))), } } /// urlへのgetリクエストを5秒でタイムアウトする。 fn get_timeout(url: &str) -> Result<(surf::StatusCode, String), Box<dyn Error>> { let timeout = async_std::task::block_on(async { async_std::future::timeout(Duration::from_secs(5), get(url)).await }); match timeout { Ok(res) => res, Err(e) => return Err(Box::new(e)), // タイムアウトしたときのエラー } } fn main() { let res = get_timeout("http://example.com"); let (status, body) = res.unwrap(); println!("{}\n{}", status, body); }