pub struct InstanceConfig {
// Exceptional settings
pub server: String,
- pub secret: String,
+ pub secret: String, // make a newytpe
pub ipif: String,
// Capped settings:
pub max_batch_down: u32,
pub max_queue_time: Duration,
pub http_timeout: Duration,
+ pub target_requests_outstanding: u32,
// Ordinary settings:
- pub target_requests_outstanding: u32,
pub addrs: Vec<IpAddr>,
pub vnetwork: Vec<CidrString>,
pub vaddr: Vec<IpAddr>,
#[derive(Debug,Clone,Hash,Eq,PartialEq)]
pub enum SectionName {
- Link { server: ServerName, client: ClientName },
+ Link(LinkName),
Client(ClientName),
Server(ServerName), // includes SERVER, which is slightly special
ServerLimit(ServerName),
}
pub use SectionName as SN;
+#[derive(Debug,Clone,Hash,Eq,PartialEq)]
+struct LinkName {
+ server: ServerName,
+ client: ClientName,
+}
+
#[derive(Debug,Clone)]
struct RawVal { val: Option<String>, loc: Arc<PathBuf> }
type SectionMap = HashMap<String, RawVal>;
let server = server.parse().context("server name in link section name")?;
if client == "LIMIT" { return SN::ServerLimit(server) }
let client = client.parse().context("client name in link section name")?;
- SN::Link { server, client }
+ SN::Link(LinkName { server, client })
}
}
}
}
+enum LinkEnd { Server, Client }
+
+struct ResolveContext<'c> {
+ agg: &'c Aggregate,
+ link: &'c LinkName,
+ end: LinkEnd,
+}
+
+impl<'c> ResolveContext<'c> {
+ fn first_of_raw(&self, key: &str,
+ sections: &[ &dyn Fn() -> SectionName ])
+ -> Option<&'c RawVal> {
+ for section in sections {
+ if let Some(raw) = self.agg.sections
+ .get(§ion())
+ .and_then(|vars: &SectionMap| vars.get(key))
+ {
+ return Some(raw)
+ }
+ }
+ None
+ }
+
+ #[throws(AE)]
+ fn first_of<T>(&self, key: &str,
+ sections: &[ &dyn Fn() -> SectionName ])
+ -> Option<T>
+ where T: FromStr
+ {
+ match self.first_of_raw(key, sections) {
+ None => None,
+ Some(raw) => Some({
+ raw.val.parse()
+ .context(key)
+ .context(r#"in section "{}""#, &raw.section)
+ .dcontext(&raw.loc)?
+ }),
+ }
+ }
+
+ pub fn ordinary<T>(&self, key: &str) -> T where T: FromStr + Default {
+ self.first_of(key, &[
+ || SN::Link(self.link.clone()),
+ || SN::Client(self.link.client.clone()),
+ || SN::Server(self.link.server.clone()),
+ || SN::Common,
+ ])?
+ .unwrap_or_default()
+ }
+
+ pub fn limited<T>(&self, key: &str) -> T
+ where T: FromStr + Default + PartialOrd
+ {
+ let val = self.ordinary(key);
+ if let Some(limit) = self.first_of(key, &[
+ || SN::LimitServer(self.link.server.clone()),
+ || SN::LimitGlobal,
+ ])? {
+ val = min(val, limit)
+ }
+ val
+ }
+
+ pub fn client<T>(&self, key: &str) -> T where T: FromStr + Default {
+ match self.end {
+ LinkEnd::Client => self.ordinary(key)?,
+ LinkEnd::Server => default(),
+ }
+ }
+ pub fn server<T>(&self, key: &str) -> T where T: FromStr + Default {
+ match self.end {
+ LinkEnd::Server => self.ordinary(key)?,
+ LinkEnd::Client => default(),
+ }
+ }
+
+ pub fn special_ipif<T>(&self, key: &str) -> T where T: FromStr + Default {
+ match self.end {
+ LinkEnd::Client => self.ordinary(key)?,
+ LinkEnd::Server => {
+ self.first_of(key, &[
+ || SN::Common,
+ || SN::Server(self.link.server.clone()),
+ ])?
+ },
+ }
+ }
+}
+
+/*
+fn resolve_instance_config() {
+ InstanceConfig {
+ max_batch_down: resolve::limited(&agg, "max_batch_down")
+ }
+}
+*/
#[throws(AE)]
pub fn read() {