diff --git a/updater/src/updater.rs b/updater/src/updater.rs index 6da14538a..24096704d 100644 --- a/updater/src/updater.rs +++ b/updater/src/updater.rs @@ -18,6 +18,7 @@ use std::fs; use std::io::Write; use std::path::{PathBuf}; use std::sync::{Arc, Weak}; +use std::time::{Duration, Instant}; use ethcore::client::{BlockId, BlockChainClient, ChainNotify}; use ethsync::{SyncProvider}; @@ -82,6 +83,8 @@ struct UpdaterState { capability: CapState, disabled: bool, + + backoff: Option<(u32, Instant)>, } /// Service for checking for updates and determining whether we can achieve consensus. @@ -260,7 +263,19 @@ impl Updater { let fetched = s.fetching.take().unwrap(); let dest = self.updates_path(&Self::update_file_name(&fetched.version)); if !dest.exists() { - let b = result.map_err(|e| (format!("Unable to fetch update ({}): {:?}", fetched.version, e), false))?; + let b = match result { + Ok(b) => { + s.backoff = None; + b + }, + Err(e) => { + let mut n = s.backoff.map(|b| b.0 + 1).unwrap_or(1); + s.backoff = Some((n, Instant::now() + Duration::from_secs(2usize.pow(n) as u64))); + + return Err((format!("Unable to fetch update ({}): {:?}", fetched.version, e), false)); + }, + }; + info!(target: "updater", "Fetched latest version ({}) OK to {}", fetched.version, b.display()); fs::create_dir_all(dest.parent().expect("at least one thing pushed; qed")).map_err(|e| (format!("Unable to create updates path: {:?}", e), true))?; fs::copy(&b, &dest).map_err(|e| (format!("Unable to copy update: {:?}", e), true))?; @@ -320,12 +335,14 @@ impl Updater { drop(s); self.fetch_done(Ok(PathBuf::new())); } else { - info!(target: "updater", "Attempting to get parity binary {}", b); - s.fetching = Some(latest.track.clone()); - drop(s); - let weak_self = self.weak_self.lock().clone(); - let f = move |r: Result| if let Some(this) = weak_self.upgrade() { this.fetch_done(r) }; - self.fetcher.fetch(b, Box::new(f)); + if s.backoff.iter().all(|&(_, instant)| Instant::now() >= instant) { + info!(target: "updater", "Attempting to get parity binary {}", b); + s.fetching = Some(latest.track.clone()); + drop(s); + let weak_self = self.weak_self.lock().clone(); + let f = move |r: Result| if let Some(this) = weak_self.upgrade() { this.fetch_done(r) }; + self.fetcher.fetch(b, Box::new(f)); + } } } } @@ -354,6 +371,11 @@ impl Updater { } let mut s = self.state.lock(); + + if s.latest != latest { + s.backoff = None; + } + s.latest = latest; s.capability = capability; }