IQ4FCHPZYGTZHCQHUIRCMUI5LCHIDSJCM2AZXGRJARWLCPPLXZOQC
KQTD46KVVWMJ3W6O55BEJLCVTNTDLUH6QT46AEFT7OU2SELXG4IAC
MU5GSJAW65PEG3BRYUKZ7O37BPHW3MOX3S5E2RFOXKGUOJEEDQ5AC
367UBQ6KNAKUEWG32R4QRJ6H7IE7NAZFOPTC3ZOE4Z6E44RV3ISQC
FBXYP7QM7SG6P2JDJVQPPCRKJE3GVYXNQ5GVV4GRDUNG6Q4ZRDJQC
Q45QHPO4HDTEZF2W4UDZSYYQ46BPEIWSW4GJILZR5HTJNLKXJABQC
I52XSRUH5RVHQBFWVMAQPTUSPAJ4KNVID2RMI3UGCVKFLYUO6WZAC
5QTMRUXNE2XNJCMLN6MQN24UEZ55EFC3LIR4PO6OPNTT5KEL7WXQC
HXEIH4UQ6EX3MAY33JK4WQUE5GUSZ673OX57JKNFXC2N2QLTXKXAC
}
async fn download_change(
client: reqwest::Client,
url: String,
mut path: PathBuf,
c: libpijul::pristine::Hash,
) -> Result<(), anyhow::Error> {
libpijul::changestore::filesystem::push_filename(&mut path, &c);
std::fs::create_dir_all(&path.parent().unwrap())?;
let path_ = path.with_extension("tmp");
let mut f = std::fs::File::create(&path_)?;
libpijul::changestore::filesystem::pop_filename(&mut path);
let c32 = c.to_base32();
let url = format!("{}/{}", url, super::DOT_DIR);
let mut delay = 1f64;
let mut res = loop {
let res = if let Ok(res) = client.get(&url).query(&[("change", &c32)]).send().await {
res
} else {
error!("HTTP error, retrying in {} seconds", delay.round());
tokio::time::delay_for(std::time::Duration::from_secs_f64(delay)).await;
delay *= 2.;
continue;
};
debug!("response {:?}", res);
if res.status().is_success() {
break res;
} else {
return Err((crate::Error::Http {
status: res.status(),
})
.into());
}
};
while let Some(chunk) = res.chunk().await? {
debug!("writing {:?}", chunk.len());
f.write_all(&chunk)?;
}
std::fs::rename(&path_, &path_.with_extension("change"))?;
Ok(())
libpijul::changestore::filesystem::push_filename(path, c);
std::fs::create_dir_all(&path.parent().unwrap())?;
let path_ = path.with_extension("tmp");
let mut f = std::fs::File::create(&path_)?;
libpijul::changestore::filesystem::pop_filename(path);
let c32 = c.to_base32();
let url = format!("{}/{}", self.url, super::DOT_DIR);
let mut res = self
.client
.get(&url)
.query(&[("change", c32)])
.send()
.await?;
debug!("response {:?}", res);
if !res.status().is_success() {
return Err((crate::Error::Http {
status: res.status(),
})
.into());
}
while let Some(chunk) = res.chunk().await? {
debug!("writing {:?}", chunk.len());
f.write_all(&chunk)?;
}
std::fs::rename(&path_, &path_.with_extension("change"))?;
if send.send(*c).await.is_err() {
debug!("err for {:?}", c);
progress.abandon();
break;
let t = std::mem::replace(
&mut pool[cur],
Some(tokio::spawn(download_change(
self.client.clone(),
self.url.clone(),
path.clone(),
*c,
))),
);
if let Some(t) = t {
t.await??;
if send.send(*c).await.is_err() {
debug!("err for {:?}", c);
progress.abandon();
break;
}