薄っぺらりん

厚くしていきたい

xv6ノートを書いた

去年の暮にxv6を読んだ。
年明けから体調が悪くて時間が空いてしまったけれど、読みながら書いたノートをmdbookでキレイにまとめて、GitHub Pagesで公開した。
6章以降は今後ちょっとずつ書いていく。

xv6ノート
https://kkmtyyz.github.io/xv6-notebook/

折角なのでGitHub Actionsを使ってみたけれど、これが無料で使えるのは本当にすごい。

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);
}

参考

How to set request timeout? #91