caio.co/de/foca

Add set_config for changing config during runtime

This patch introduces `Foca::set_config` which allows changing (some)
configuration parameters while Foca is running and swimming.
Id
81a3e74f8f0488034a387d17bab74f20a90eb2ea
Author
Caio
Commit time
2022-05-08T14:57:54+02:00

Modified src/error.rs

@@ -70,6 +70,13
///
/// Doesn't affect Foca's state.
CustomBroadcast(anyhow::Error),
+
+ /// Configuration change not allowed.
+ ///
+ /// Doesn't affact Foca's state.
+ ///
+ /// See [`crate::Foca::set_config`].
+ InvalidConfig,
}

impl PartialEq for Error {
@@ -92,6 +99,7
(Error::DataFromOurselves, Error::DataFromOurselves) => true,
(Error::IndirectForOurselves, Error::IndirectForOurselves) => true,
(Error::MalformedPacket, Error::MalformedPacket) => true,
+ (Error::InvalidConfig, Error::InvalidConfig) => true,

// Instead of a catch-all here, we explicitly enumerate our variants
// so that when/if new errors are added we don't silently introduce
@@ -107,6 +115,7
(Error::DataFromOurselves, _) => false,
(Error::IndirectForOurselves, _) => false,
(Error::MalformedPacket, _) => false,
+ (Error::InvalidConfig, _) => false,
}
}
}
@@ -137,6 +146,7
Error::Encode(err) => err.fmt(formatter),
Error::Decode(err) => err.fmt(formatter),
Error::CustomBroadcast(err) => err.fmt(formatter),
+ Error::InvalidConfig => formatter.write_str("Invalid configuration"),
}
}
}

Modified src/lib.rs

@@ -616,6 +616,29
self.custom_broadcasts.len()
}

+ /// Replaces the current configuration with a new one.
+ ///
+ /// Most of the time a static configuration is more than enough, but
+ /// for use-cases where the cluster size can drastically change during
+ /// normal operations, changing the configuration parameters is a
+ /// nicer alternative to recreating the Foca instance.
+ ///
+ /// Presently, attempting to change [`Config::probe_period`] or
+ /// [`Config::probe_rtt`] results in [`Error::InvalidConfig`]; For
+ /// such cases it's recommended to recreate your Foca instance. When
+ /// an error occurrs, every configuration parameter remains
+ /// unchanged.
+ pub fn set_config(&mut self, config: Config) -> Result<()> {
+ if self.config.probe_period != config.probe_period
+ || self.config.probe_rtt != config.probe_rtt
+ {
+ Err(Error::InvalidConfig)
+ } else {
+ self.config = config;
+ Ok(())
+ }
+ }
+
/// Handle data received from the network.
///
/// Data larger than the configured limit will be rejected. Errors are
@@ -1429,6 +1452,31
);
assert_eq!(Ok(()), foca.change_identity(ID::new(43), &mut runtime));
assert_eq!(&ID::new(43), foca.identity());
+ }
+
+ #[test]
+ fn cant_change_config_probe_timers() {
+ let mut foca = Foca::new(ID::new(1), config(), rng(), codec());
+
+ let mut bad_config = config();
+ bad_config.probe_rtt += Duration::from_millis(1);
+
+ assert_eq!(
+ Err(Error::InvalidConfig),
+ foca.set_config(bad_config),
+ "must not be able to change probe_rtt"
+ );
+
+ let mut bad_config = config();
+ bad_config.probe_period -= Duration::from_secs(1);
+
+ assert_eq!(
+ Err(Error::InvalidConfig),
+ foca.set_config(bad_config),
+ "must not be able to change probe_period"
+ );
+
+ assert_eq!(Ok(()), foca.set_config(config()));
}

#[test]