Skip to content

Commit

Permalink
download_sysext: retry to download 10 times at max
Browse files Browse the repository at this point in the history
If HTTP client fails to download, retry to download once in 500 msec,
up to 10 times.
  • Loading branch information
dongsupark committed Dec 14, 2023
1 parent f75d089 commit 278002f
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 6 deletions.
18 changes: 12 additions & 6 deletions src/download.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use anyhow::{Context, Result, bail};
use anyhow::{anyhow, Context, Result, bail};
use std::io::{BufReader, Read, Seek, SeekFrom, Write};
use std::io;
use std::fs::File;
Expand All @@ -10,6 +10,8 @@ use reqwest::StatusCode;

use sha2::{Sha256, Digest};

const MAX_DOWNLOAD_RETRY: u32 = 10;

pub struct DownloadResult<W: std::io::Write> {
pub hash: omaha::Hash<omaha::Sha256>,
pub data: W,
Expand Down Expand Up @@ -65,11 +67,15 @@ where
{
let client_url = url.clone();

#[rustfmt::skip]
let mut res = client.get(url)
.send()
.await
.context(format!("client get and send({:?}) failed", client_url.as_str()))?;
let mut res = crate::retry_loop(
|| {
let res = client.get(url.clone()).send();
Ok(res)
},
MAX_DOWNLOAD_RETRY,
)
.map_err(|err: anyhow::Error| anyhow!("client get & send failed with err {:?}", err))?
.await?;

// Redirect was already handled at this point, so there is no need to touch
// response or url again. Simply print info and continue.
Expand Down
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,7 @@ pub use download::DownloadResult;
pub use download::download_and_hash;
pub use download::hash_on_disk_sha256;

mod util;
pub use util::retry_loop;

pub mod request;
23 changes: 23 additions & 0 deletions src/util.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use tokio::runtime::Handle;
use tokio::time::{sleep, Duration};

pub fn retry_loop<F, T, E>(mut func: F, max_tries: u32) -> Result<T, E>
where
F: FnMut() -> Result<T, E>,
{
let mut tries = 0;

loop {
match func() {
ok @ Ok(_) => return ok,
err @ Err(_) => {
tries += 1;

if tries >= max_tries {
return err;
}
Handle::current().block_on(sleep(Duration::from_millis(500)));
}
}
}
}

0 comments on commit 278002f

Please sign in to comment.