Skip to content

Commit

Permalink
[skip ci] Rework config (draft)
Browse files Browse the repository at this point in the history
  • Loading branch information
sashacmc committed Mar 5, 2024
1 parent e59af20 commit 2f5eff2
Show file tree
Hide file tree
Showing 4 changed files with 385 additions and 242 deletions.
24 changes: 18 additions & 6 deletions commons/zenoh-config/src/defaults.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,13 +212,25 @@ impl Default for SharedMemoryConf {
}
}

impl Default for ConnectionRetryConf {
fn default() -> Self {
impl ConnectionRetryModeDependentConf {
pub fn default_connect() -> Self {
Self {
timeout_ms: ModeDependentValue::Unique(-1),
try_timeout_ms: ModeDependentValue::Unique(10_000),
period_init_ms: ModeDependentValue::Unique(1000),
period_max_ms: ModeDependentValue::Unique(4000),
period_increase_factor: ModeDependentValue::Unique(2.),
fail_exit: ModeDependentValue::Unique(false),
}
}
pub fn default_listen() -> Self {
Self {
count: 0,
timeout_ms: 1000,
timeout_increase_factor: 1.,
exit_on_fail: ModeDependentValue::Unique(true),
timeout_ms: ModeDependentValue::Unique(0),
try_timeout_ms: ModeDependentValue::Unique(10_000),
period_init_ms: ModeDependentValue::Unique(1000),
period_max_ms: ModeDependentValue::Unique(4000),
period_increase_factor: ModeDependentValue::Unique(2.),
fail_exit: ModeDependentValue::Unique(true),
}
}
}
258 changes: 58 additions & 200 deletions commons/zenoh-config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,10 @@
//! Configuration to pass to `zenoh::open()` and `zenoh::scout()` functions and associated constants.
pub mod defaults;
mod include;

use include::recursive_include;
use secrecy::{CloneableSecret, DebugSecret, Secret, SerializableSecret, Zeroize};
use serde::{
de::{self, MapAccess, Visitor},
Deserialize, Serialize,
};
use serde::{Deserialize, Serialize};
use serde_json::Value;
#[allow(unused_imports)]
use std::convert::TryFrom; // This is a false positive from the rust analyser
Expand All @@ -29,7 +27,6 @@ use std::{
collections::HashSet,
fmt,
io::Read,
marker::PhantomData,
net::SocketAddr,
path::Path,
sync::{Arc, Mutex, MutexGuard, Weak},
Expand All @@ -47,6 +44,9 @@ use zenoh_protocol::{
use zenoh_result::{bail, zerror, ZResult};
use zenoh_util::LibLoader;

pub mod mode_dependend;
pub use mode_dependend::*;

// Wrappers for secrecy of values
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
pub struct SecretString(String);
Expand Down Expand Up @@ -99,15 +99,57 @@ pub struct DownsamplingItemConf {

#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct ConnectionRetryConf {
//TODO(sashacmc): add comments, and infinit value for counter
// ModeDependentValue:
// 1) only for exit_on_fail
// 2) for all
// 3) for no one (we have connect and listen config, they already separate)
pub count: u32,
pub timeout_ms: u64,
pub timeout_increase_factor: f32,
pub exit_on_fail: ModeDependentValue<bool>,
pub timeout_ms: i64,
pub try_timeout_ms: i64,
pub period_init_ms: i64,
pub period_max_ms: i64,
pub period_increase_factor: f64,
pub fail_exit: bool,
}

#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct ConnectionRetryModeDependentConf {
pub timeout_ms: ModeDependentValue<i64>,
pub try_timeout_ms: ModeDependentValue<i64>,
pub period_init_ms: ModeDependentValue<i64>,
pub period_max_ms: ModeDependentValue<i64>,
pub period_increase_factor: ModeDependentValue<f64>,
pub fail_exit: ModeDependentValue<bool>,
}

impl ConnectionRetryModeDependentConf {
pub fn get(
&self,
whatami: WhatAmI,
default: ConnectionRetryModeDependentConf,
) -> ConnectionRetryConf {
ConnectionRetryConf {
timeout_ms: *self
.timeout_ms
.get(whatami)
.unwrap_or(&default.timeout_ms.get(whatami).unwrap()),
try_timeout_ms: *self
.try_timeout_ms
.get(whatami)
.unwrap_or(&default.timeout_ms.get(whatami).unwrap()),
period_init_ms: *self
.period_init_ms
.get(whatami)
.unwrap_or(&default.period_init_ms.get(whatami).unwrap()),
period_max_ms: *self
.period_max_ms
.get(whatami)
.unwrap_or(&default.period_max_ms.get(whatami).unwrap()),
period_increase_factor: *self
.period_increase_factor
.get(whatami)
.unwrap_or(&default.period_increase_factor.get(whatami).unwrap()),
fail_exit: *self
.fail_exit
.get(whatami)
.unwrap_or(&default.fail_exit.get(whatami).unwrap()),
}
}
}

pub trait ConfigValidator: Send + Sync {
Expand Down Expand Up @@ -192,13 +234,13 @@ validated_struct::validator! {
pub connect: #[derive(Default)]
ConnectConfig {
pub endpoints: Vec<EndPoint>,
pub retry: Option<ConnectionRetryConf>,
pub retry: Option<ConnectionRetryModeDependentConf>,
},
/// Which endpoints to listen on. `zenohd` will add `tcp/[::]:7447` to these locators if left empty.
pub listen: #[derive(Default)]
ListenConfig {
pub endpoints: Vec<EndPoint>,
pub retry: Option<ConnectionRetryConf>,
pub retry: Option<ConnectionRetryModeDependentConf>,
},
pub scouting: #[derive(Default)]
ScoutingConf {
Expand Down Expand Up @@ -1260,190 +1302,6 @@ impl validated_struct::ValidatedMap for PluginsConfig {
}
}

pub trait ModeDependent<T> {
fn router(&self) -> Option<&T>;
fn peer(&self) -> Option<&T>;
fn client(&self) -> Option<&T>;
#[inline]
fn get(&self, whatami: WhatAmI) -> Option<&T> {
match whatami {
WhatAmI::Router => self.router(),
WhatAmI::Peer => self.peer(),
WhatAmI::Client => self.client(),
}
}
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ModeValues<T> {
#[serde(skip_serializing_if = "Option::is_none")]
router: Option<T>,
#[serde(skip_serializing_if = "Option::is_none")]
peer: Option<T>,
#[serde(skip_serializing_if = "Option::is_none")]
client: Option<T>,
}

impl<T> ModeDependent<T> for ModeValues<T> {
#[inline]
fn router(&self) -> Option<&T> {
self.router.as_ref()
}

#[inline]
fn peer(&self) -> Option<&T> {
self.peer.as_ref()
}

#[inline]
fn client(&self) -> Option<&T> {
self.client.as_ref()
}
}

#[derive(Clone, Debug)]
pub enum ModeDependentValue<T> {
Unique(T),
Dependent(ModeValues<T>),
}

impl<T> ModeDependent<T> for ModeDependentValue<T> {
#[inline]
fn router(&self) -> Option<&T> {
match self {
Self::Unique(v) => Some(v),
Self::Dependent(o) => o.router(),
}
}

#[inline]
fn peer(&self) -> Option<&T> {
match self {
Self::Unique(v) => Some(v),
Self::Dependent(o) => o.peer(),
}
}

#[inline]
fn client(&self) -> Option<&T> {
match self {
Self::Unique(v) => Some(v),
Self::Dependent(o) => o.client(),
}
}
}

impl<T> serde::Serialize for ModeDependentValue<T>
where
T: Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
match self {
ModeDependentValue::Unique(value) => value.serialize(serializer),
ModeDependentValue::Dependent(options) => options.serialize(serializer),
}
}
}
impl<'a> serde::Deserialize<'a> for ModeDependentValue<bool> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'a>,
{
struct UniqueOrDependent<U>(PhantomData<fn() -> U>);

impl<'de> Visitor<'de> for UniqueOrDependent<ModeDependentValue<bool>> {
type Value = ModeDependentValue<bool>;

fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("bool or mode dependent bool")
}

fn visit_bool<E>(self, value: bool) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(ModeDependentValue::Unique(value))
}

fn visit_map<M>(self, map: M) -> Result<Self::Value, M::Error>
where
M: MapAccess<'de>,
{
ModeValues::deserialize(de::value::MapAccessDeserializer::new(map))
.map(ModeDependentValue::Dependent)
}
}
deserializer.deserialize_any(UniqueOrDependent(PhantomData))
}
}

impl<'a> serde::Deserialize<'a> for ModeDependentValue<WhatAmIMatcher> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'a>,
{
struct UniqueOrDependent<U>(PhantomData<fn() -> U>);

impl<'de> Visitor<'de> for UniqueOrDependent<ModeDependentValue<WhatAmIMatcher>> {
type Value = ModeDependentValue<WhatAmIMatcher>;

fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("WhatAmIMatcher or mode dependent WhatAmIMatcher")
}

fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
WhatAmIMatcherVisitor {}
.visit_str(value)
.map(ModeDependentValue::Unique)
}

fn visit_map<M>(self, map: M) -> Result<Self::Value, M::Error>
where
M: MapAccess<'de>,
{
ModeValues::deserialize(de::value::MapAccessDeserializer::new(map))
.map(ModeDependentValue::Dependent)
}
}
deserializer.deserialize_any(UniqueOrDependent(PhantomData))
}
}

impl<T> ModeDependent<T> for Option<ModeDependentValue<T>> {
#[inline]
fn router(&self) -> Option<&T> {
match self {
Some(ModeDependentValue::Unique(v)) => Some(v),
Some(ModeDependentValue::Dependent(o)) => o.router(),
None => None,
}
}

#[inline]
fn peer(&self) -> Option<&T> {
match self {
Some(ModeDependentValue::Unique(v)) => Some(v),
Some(ModeDependentValue::Dependent(o)) => o.peer(),
None => None,
}
}

#[inline]
fn client(&self) -> Option<&T> {
match self {
Some(ModeDependentValue::Unique(v)) => Some(v),
Some(ModeDependentValue::Dependent(o)) => o.client(),
None => None,
}
}
}

#[macro_export]
macro_rules! unwrap_or_default {
($val:ident$(.$field:ident($($param:ident)?))*) => {
Expand Down
Loading

0 comments on commit 2f5eff2

Please sign in to comment.