message: service.rs: Start a thread per network
  This allows us to run net_sync() in continuous mode.
diff: -use config::{Config, Networks};
  +use config::{Config, Networks, Network};
  use exe_common::sync;
  use handlers;
  use iron;
  @@ -8,10 +8,8 @@ use std::thread;
  use std::time::Duration;
  use net;
  -static NETWORK_REFRESH_FREQUENCY: Duration = Duration::from_secs(60 * 10);
  -
  pub fn start(cfg: Config) {
  - let _refresher = if cfg.sync { Some(start_networks_refresher(cfg.clone())) } else { None };
  + let _refreshers = if cfg.sync { Some(start_networks_refreshers(cfg.clone())) } else { None };
  let _server = start_http_server(&cfg, Arc::new(cfg.get_networks().unwrap()));
  // XXX: consider installing a signal handler to initiate a graceful shutdown here
  @@ -31,42 +29,32 @@ fn start_http_server(cfg: &Config, networks: Arc<Networks>) -> iron::Listening {
  }
  // TODO: make this a struct which receives a shutdown message on a channel and then wraps itself up
  -fn start_networks_refresher(cfg: Config) -> thread::JoinHandle<()> {
  - thread::spawn(move || {
  - info!("Refreshing every {:?}", NETWORK_REFRESH_FREQUENCY);
  - loop {
  +fn start_networks_refreshers(cfg: Config) -> Vec<thread::JoinHandle<()>> {
  + let mut threads = vec![];
  match cfg.get_networks() {
  - Err(err) => warn!("Refresh failed: {:?}", err),
  + Err(err) => panic!("Unable to get networks: {:?}", err),
  Ok(networks) => {
  - refresh_networks(networks);
  - info!("Refresh completed")
  + for (label, net) in networks.into_iter() {
  + threads.push(thread::spawn(move || {
  + loop {
  + refresh_network(&label, &net);
  + // In case of an error, wait a while before retrying.
  + thread::sleep(Duration::from_secs(10));
  + }
  + }));
  }
  }
  - thread::sleep(NETWORK_REFRESH_FREQUENCY);
  }
  - })
  + threads
  }
  // XXX: how do we want to report partial failures?
  -fn refresh_networks(networks: Networks) {
  - for (label, net) in networks.into_iter() {
  +fn refresh_network(label: &str, net: &Network) {
  info!("Refreshing network {:?}", label);
  - match Arc::try_unwrap(net.storage) {
  - // Cannot just use `.unwrap()` because that requires a debug instance
  - Err(_) => warn!(
  - "Refresh for network {} failed: Unable to access storage",
  - label
  - ),
  - Ok(storage) => {
  - let netcfg_file = storage.config.get_config_file();
  +
  + let netcfg_file = net.storage.config.get_config_file();
  let net_cfg = net::Config::from_file(&netcfg_file).expect("no network config present");
  - // FIXME: sync net_sync() now runs continuously, this
  - // doesn't return (unless there is an error). Maybe we
  - // should use a separate thread for every network?
  - sync::net_sync(&mut sync::get_peer(&label, &net_cfg, true), &net_cfg, &storage, false)
  + sync::net_sync(&mut sync::get_peer(&label, &net_cfg, true), &net_cfg, &net.storage, false)
  .unwrap_or_else(|err| { warn!("Sync failed: {:?}", err) });
  }
  - }
  - }
  -}
  