Skip to content

Commit

Permalink
feat: avoid duplicate autoconnection attempt (#1742)
Browse files Browse the repository at this point in the history
* feat: avoid duplicate autoconnection attempt

Gossip autoconnection could result in two nodes attempting to connect
to each other concurrently.
To fix this issue, only one node initiate the connection now. The
selection criteria is arbitrary but deterministic, currently the
greater zid of both.

* refactor: extract autoconnect node selection in a dedicated function

* refactor: add a configuration option for autoconnection

* revert: revert JSON config formatting

* fix: lint

* feat: add an "always" autoconnection strategy

* docs: document DEFAULT_CONFIG.json5

* Update DEFAULT_CONFIG.json5

Co-authored-by: Oussama Teffahi <70609372+oteffahi@users.noreply.github.com>

* feat: make strategy dependent on the connected node

* Update DEFAULT_CONFIG.json5

Co-authored-by: Oussama Teffahi <70609372+oteffahi@users.noreply.github.com>

* Update DEFAULT_CONFIG.json5

Co-authored-by: Oussama Teffahi <70609372+oteffahi@users.noreply.github.com>

* fix: remove dead code

* feat: introduce target-dependent value

* fix: lint

* fix: remove dead code

* fix: remove debug code

---------

Co-authored-by: Oussama Teffahi <70609372+oteffahi@users.noreply.github.com>
  • Loading branch information
wyfo and oteffahi authored Feb 7, 2025
1 parent 69f810d commit ed56b57
Show file tree
Hide file tree
Showing 16 changed files with 539 additions and 112 deletions.
111 changes: 104 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

97 changes: 49 additions & 48 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,44 +14,44 @@
[workspace]
resolver = "2"
members = [
"commons/zenoh-buffers",
"commons/zenoh-codec",
"commons/zenoh-collections",
"commons/zenoh-config",
"commons/zenoh-core",
"commons/zenoh-crypto",
"commons/zenoh-keyexpr",
"commons/zenoh-macros",
"commons/zenoh-protocol",
"commons/zenoh-result",
"commons/zenoh-shm",
"commons/zenoh-sync",
"commons/zenoh-task",
"commons/zenoh-util",
"commons/zenoh-runtime",
"examples",
"io/zenoh-link",
"io/zenoh-link-commons",
"io/zenoh-links/zenoh-link-quic/",
"io/zenoh-links/zenoh-link-serial",
"io/zenoh-links/zenoh-link-tcp/",
"io/zenoh-links/zenoh-link-tls/",
"io/zenoh-links/zenoh-link-udp/",
"io/zenoh-links/zenoh-link-unixsock_stream/",
"io/zenoh-links/zenoh-link-ws/",
"io/zenoh-links/zenoh-link-unixpipe/",
"io/zenoh-links/zenoh-link-vsock/",
"io/zenoh-transport",
"plugins/zenoh-backend-example",
"plugins/zenoh-plugin-example",
"plugins/zenoh-backend-traits",
"plugins/zenoh-plugin-rest",
"plugins/zenoh-plugin-storage-manager",
"plugins/zenoh-plugin-trait",
"zenoh",
"zenoh-ext",
"zenoh-ext/examples",
"zenohd",
"commons/zenoh-buffers",
"commons/zenoh-codec",
"commons/zenoh-collections",
"commons/zenoh-config",
"commons/zenoh-core",
"commons/zenoh-crypto",
"commons/zenoh-keyexpr",
"commons/zenoh-macros",
"commons/zenoh-protocol",
"commons/zenoh-result",
"commons/zenoh-shm",
"commons/zenoh-sync",
"commons/zenoh-task",
"commons/zenoh-util",
"commons/zenoh-runtime",
"examples",
"io/zenoh-link",
"io/zenoh-link-commons",
"io/zenoh-links/zenoh-link-quic/",
"io/zenoh-links/zenoh-link-serial",
"io/zenoh-links/zenoh-link-tcp/",
"io/zenoh-links/zenoh-link-tls/",
"io/zenoh-links/zenoh-link-udp/",
"io/zenoh-links/zenoh-link-unixsock_stream/",
"io/zenoh-links/zenoh-link-ws/",
"io/zenoh-links/zenoh-link-unixpipe/",
"io/zenoh-links/zenoh-link-vsock/",
"io/zenoh-transport",
"plugins/zenoh-backend-example",
"plugins/zenoh-plugin-example",
"plugins/zenoh-backend-traits",
"plugins/zenoh-plugin-rest",
"plugins/zenoh-plugin-storage-manager",
"plugins/zenoh-plugin-trait",
"zenoh",
"zenoh-ext",
"zenoh-ext/examples",
"zenohd",
]
exclude = ["ci/nostd-check", "ci/valgrind-check"]

Expand All @@ -61,11 +61,11 @@ version = "1.2.1"
repository = "https://github.com/eclipse-zenoh/zenoh"
homepage = "http://zenoh.io"
authors = [
"kydos <angelo@icorsaro.net>",
"Julien Enoch <julien@enoch.fr>",
"Olivier Hécart <olivier.hecart@zettascale.tech>",
"Luca Cominardi <luca.cominardi@zettascale.tech>",
"Pierre Avital <pierre.avital@zettascale.tech>",
"kydos <angelo@icorsaro.net>",
"Julien Enoch <julien@enoch.fr>",
"Olivier Hécart <olivier.hecart@zettascale.tech>",
"Luca Cominardi <luca.cominardi@zettascale.tech>",
"Pierre Avital <pierre.avital@zettascale.tech>",
]
edition = "2021"
license = "EPL-2.0 OR Apache-2.0"
Expand Down Expand Up @@ -144,9 +144,9 @@ ringbuffer-spsc = "0.1.9"
rsa = "0.9"
rustc_version = "0.4.1"
rustls = { version = "0.23.13", default-features = false, features = [
"logging",
"tls12",
"ring",
"logging",
"tls12",
"ring",
] }
rustls-native-certs = "0.8.0"
rustls-pemfile = "2.1.3"
Expand All @@ -155,9 +155,10 @@ rustls-pki-types = "1.8.0"
schemars = { version = "0.8.21", features = ["either"] }
secrecy = { version = "0.8.0", features = ["serde", "alloc"] }
serde = { version = "1.0.210", default-features = false, features = [
"derive",
"derive",
] } # Default features are disabled due to usage in no_std crates
serde_json = "1.0.128"
serde_with = "3.12.0"
serde_yaml = "0.9.34"
static_init = "1.0.3"
stabby = "36.1.1"
Expand All @@ -182,7 +183,7 @@ unzip-n = "0.1.2"
url = "2.5.2"
urlencoding = "2.1.3"
uuid = { version = "1.10.0", default-features = false, features = [
"v4",
"v4",
] } # Default features are disabled due to usage in no_std crates
validated_struct = "2.1.0"
vec_map = "0.8.2"
Expand Down
26 changes: 26 additions & 0 deletions DEFAULT_CONFIG.json5
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,19 @@
/// or different values for router, peer or client mode (e.g. autoconnect: { router: [], peer: ["router", "peer"] }).
/// Each value is a list of: "peer", "router" and/or "client".
autoconnect: { router: [], peer: ["router", "peer"], client: ["router"] },
/// Strategy for autoconnection, mainly to avoid nodes connecting to each other redundantly.
/// Possible options are:
/// - "always": always attempt to autoconnect, may result in redundant connection which will then be closed.
/// - "greater-zid": attempt to connect to another node only if its own zid is greater than the other's.
/// If both nodes use this strategy, only one will attempt the connection.
/// This strategy may not be suited if one of the nodes is not reachable by the other one, for example
/// because of a private IP.
/// Accepts a single value (e.g. autoconnect: "always") which applies whatever node would be auto-connected to,
/// or different values for router and/or peer depending on the type of node detected
/// (e.g. autoconnect_strategy : { "to-router": "always", "to-peer": "greater-zid" }),
/// or different values for router or peer mode
/// (e.g. autoconnect_strategy : { peer: { "to-router": "always", "to-peer": "greater-zid" } }).
autoconnect_strategy: { peer: { "to-router": "always", "to-peer": "always" } },
/// Whether or not to listen for scout messages on UDP multicast and reply to them.
listen: true,
},
Expand All @@ -161,6 +174,19 @@
/// or different values for router or peer mode (e.g. autoconnect: { router: [], peer: ["router", "peer"] }).
/// Each value is a list of: "peer" and/or "router".
autoconnect: { router: [], peer: ["router", "peer"] },
/// Strategy for autoconnection, mainly to avoid nodes connecting to each other redundantly.
/// Possible options are:
/// - "always": always attempt to autoconnect, may result in redundant connection which will then be closed.
/// - "greater-zid": attempt to connect to another node only if its own zid is greater than the other's.
/// If both nodes use this strategy, only one will attempt the connection.
/// This strategy may not be suited if one of the nodes is not reachable by the other one, for example
/// because of a private IP.
/// Accepts a single value (e.g. autoconnect: "always") which applies whatever node would be auto-connected to,
/// or different values for router and/or peer depending on the type of node detected
/// (e.g. autoconnect_strategy : { "to-router": "always", "to-peer": "greater-zid" }),
/// or different values for router or peer mode
/// (e.g. autoconnect_strategy : { peer: { "to-router": "always", "to-peer": "greater-zid" } }).
autoconnect_strategy: { peer: { "to-router": "always", "to-peer": "always" } },
},
},

Expand Down
1 change: 1 addition & 0 deletions commons/zenoh-config/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ json5 = { workspace = true }
num_cpus = { workspace = true }
serde = { workspace = true, features = ["default"] }
serde_json = { workspace = true }
serde_with = { workspace = true }
serde_yaml = { workspace = true }
validated_struct = { workspace = true, features = ["json5", "json_get"] }
zenoh-core = { workspace = true }
Expand Down
Loading

0 comments on commit ed56b57

Please sign in to comment.