clean up export, add module level docs
- public NetworkCoordinate so it’s easer to just `use vivaldi_nc::NetworkCoordinate` - add module level docs and examples in lib.rs - cleanup README Signed-off-by: Stephen Waits <steve@waits.net>
This commit is contained in:
3 files changed
+143
-13
No files matched your search
@@ -72,7 +72,7 @@ Each node in the network should create a `NetworkCoordinate` (NC). The node
|
||||
uses this structure to track its latency position in the entire network.
|
||||
|
||||
```rust
|
||||
use vivaldi_nc::network_coordinate::NetworkCoordinate;
|
||||
use vivaldi_nc::NetworkCoordinate;
|
||||
|
||||
// create a 2-dimensional NetworkCoordinate to track my position
|
||||
let mut my_position = NetworkCoordinate::<2>::new();
|
||||
@@ -107,10 +107,6 @@ by Serde, including text formats like [JSON](https://github.com/serde-rs/json)
|
||||
and compact binary formats like [bincode](https://crates.io/crates/bincode) and
|
||||
[MessagePack](https://github.com/3Hren/msgpack-rust).
|
||||
|
||||
### Features
|
||||
|
||||
### Examples
|
||||
|
||||
## Dependencies
|
||||
|
||||
One design goal of this crate is to minimize dependencies. When dependencies
|
||||
@@ -131,7 +127,7 @@ This crate depends on:
|
||||
`Vector<T,N>` uses a const generic length, we use this to help derive
|
||||
`Deserialize`.
|
||||
|
||||
## Alternative implementations
|
||||
## Design Goals & Alternatives
|
||||
|
||||
Several crates implemented Vivaldi NC before this one. So, why another?
|
||||
|
||||
@@ -149,6 +145,8 @@ I had several design goals which the existing crates didn't satisfy:
|
||||
rigamarole. Support `serde` traits by default.
|
||||
4. Well documented. Well tested. This varies by the crates.
|
||||
|
||||
### Other Vivaldi NC Implementations
|
||||
|
||||
All of that said, those other rust implementations might work best for you.
|
||||
Here are the ones I know of today:
|
||||
|
||||
@@ -156,7 +154,7 @@ Here are the ones I know of today:
|
||||
- [violin](https://crates.io/crates/violin)
|
||||
- [vivaldi](https://crates.io/crates/vivaldi)
|
||||
|
||||
## Other Algorithms
|
||||
### Other NC Algorithms
|
||||
|
||||
Vivaldi is about the simplest distributed NC algorithm out there. That
|
||||
simplicity combined with its reasonably good performance is a reason why it's
|
||||
@@ -164,6 +162,46 @@ popular.
|
||||
|
||||
But it's far from the only choice. Here are links to other NC algorithms:
|
||||
|
||||
- TODO: list algorithms
|
||||
- TODO: list algorithms
|
||||
- TODO: list algorithms
|
||||
- [Pharos](https://en.wikipedia.org/wiki/Pharos_Network_Coordinates)
|
||||
- [Phoenix](https://en.wikipedia.org/wiki/Phoenix_Network_Coordinates)
|
||||
|
||||
Search your favorite research paper index for "network coordinates" and you'll
|
||||
find many more.
|
||||
|
||||
## Getting Help or Contributing
|
||||
|
||||
To get help or discuss this crate, please use
|
||||
[`vivaldi-nc-discuss@`](https://lists.sr.ht/~swaits/vivaldi-nc-discuss).
|
||||
|
||||
Discussion related to development or patch submissions should go to
|
||||
[`vivaldi-nc-devel@`](https://lists.sr.ht/~swaits/vivaldi-nc-devel).
|
||||
|
||||
Patchsets should use [git-send-email](https://git-send-email.io/) or the [sr.ht
|
||||
UI](https://git.sr.ht/~swaits/vivaldi-nc/send-email) (easiest IMO).
|
||||
|
||||
Patch submitters implicitly agree that all contributions they submit fall under
|
||||
the MIT license.
|
||||
|
||||
## License
|
||||
|
||||
> MIT License
|
||||
>
|
||||
> Copyright (c) 2023 Stephen Waits
|
||||
>
|
||||
> Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
> of this software and associated documentation files (the "Software"), to deal
|
||||
> in the Software without restriction, including without limitation the rights
|
||||
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
> copies of the Software, and to permit persons to whom the Software is
|
||||
> furnished to do so, subject to the following conditions:
|
||||
>
|
||||
> The above copyright notice and this permission notice shall be included in all
|
||||
> copies or substantial portions of the Software.
|
||||
>
|
||||
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
> SOFTWARE.
|
||||
+92
@@ -1,4 +1,96 @@
|
||||
//! Vivaldi Network Coordinates with a simple interface
|
||||
//!
|
||||
//! Network Coordinates (NC) are a way to represent a node's position in a network's
|
||||
//! latency space. Nodes with low latency (ping or round trip time) between each
|
||||
//! other will be close to each other in this latency space. Nodes with high latency between them
|
||||
//! will be far from each other.
|
||||
//!
|
||||
//! This is an implementation of Vivaldi Network Coordinates, a specific NC
|
||||
//! algorithm, with a simple interface and few dependencies. Vivaldi coordinates
|
||||
//! are typically used in distributed networking applications, like p2p networks.
|
||||
//! They allow each node in the network to estimate its position in a latency space
|
||||
//! in a distributed way, with no central authority. This enables nodes to
|
||||
//! understand estimated latency to any other node in the system.
|
||||
//!
|
||||
//! To learn more, see the [Vivaldi coordinates article on
|
||||
//! Wikipedia](https://en.wikipedia.org/wiki/Vivaldi_coordinates) or [the original
|
||||
//! paper](http://conferences.sigcomm.org/sigcomm/2004/papers/p426-dabek111111.pdf) (Frank Dabek,
|
||||
//! Russ Cox, Frans Kaashoek, Robert Morris (2004)).
|
||||
//!
|
||||
//! # Usage
|
||||
//!
|
||||
//! This crate exports a single struct, [`NetworkCoordinate`]. Typical use of Vivaldi NCs for a
|
||||
//! distributed network works like this:
|
||||
//!
|
||||
//! 1. Each node in the network has its own instance of [`NetworkCoordinate`]. *See "Note on
|
||||
//! dimensionality" below.*
|
||||
//! 2. Every node occasionally sends its [`NetworkCoordinate`] to some or all other nodes through
|
||||
//! the network overlay.
|
||||
//! 3. Whenever a node receives a remote coordinate, it updates its local coordinate with the
|
||||
//! actual measured round trip time (RTT or "ping time") between itself and that node to improve
|
||||
//! its own position and thus reduce its estimation error.
|
||||
//! 4. Any node can estimate its RTT to any other [`NetworkCoordinate`] it's aware of.
|
||||
//!
|
||||
//! Importantly, all updates in this system are performed locally. No central authority is needed
|
||||
//! to build the network latency maps. It's fully distributed.
|
||||
//!
|
||||
//! **Note on dimensionality:** Typically 2D or 3D Vivaldi coordinates (i.e. `NetworkCoordinate<2>` or
|
||||
//! `NetworkCoordinate<3>`) are sufficient. Higher dimensions don't add much accuracy and aren't
|
||||
//! generally worth it. That said, you're welcome to use any dimension you like.
|
||||
//!
|
||||
//! # Examples
|
||||
//!
|
||||
//! In the first example, we simulate receving a remote NC, measuring ping, and updating our NC
|
||||
//! accordingly.
|
||||
//!
|
||||
//! ```
|
||||
//! use vivaldi_nc::NetworkCoordinate;
|
||||
//!
|
||||
//! // create our local NC as a 3-dimensional Vivaldi coordinate
|
||||
//! let mut my_nc = NetworkCoordinate::<3>::new();
|
||||
//!
|
||||
//! // mock up a remote NC for the sake of this example (normally the node would actually receive
|
||||
//! // this from a remote node)
|
||||
//! let received_msg = "{\"position\":[{\"inner\":[1.5,0.5,2.0]},0.1],\"error\":1.0}";
|
||||
//! let remote_nc: NetworkCoordinate<3> = serde_json::from_str(received_msg).unwrap();
|
||||
//!
|
||||
//! // mock up a measured RTT between us and that node (normally the nodes would coordinate
|
||||
//! // measuring this together)
|
||||
//! let rtt_actual = std::time::Duration::from_millis(78);
|
||||
//!
|
||||
//! // with the actual RTT in hand, we can update our NC to improve its accuracy
|
||||
//! my_nc.update(&remote_nc, rtt_actual);
|
||||
//!
|
||||
//! // by doing this iteratively (and forever), all NCs in the network will converge to better
|
||||
//! // represent the actual latency space of the network
|
||||
//! ```
|
||||
//!
|
||||
//! In this second example, we simulate receving a NC from another node indirectly; likely
|
||||
//! forwarded to us by someone else. And in this case, we aren't measuring the actual RTT. Instead,
|
||||
//! we're using the NCs to estimate RTT.
|
||||
//!
|
||||
//! ```
|
||||
//! use vivaldi_nc::NetworkCoordinate;
|
||||
//!
|
||||
//! // create our local NC as a 3-dimensional Vivaldi coordinate
|
||||
//! let mut my_nc = NetworkCoordinate::<3>::new();
|
||||
//!
|
||||
//! // mock up a remote NC for the sake of this example (normally the node would actually receive
|
||||
//! // this from a remote node)
|
||||
//! let received_msg = "{\"position\":[{\"inner\":[1.5,0.5,2.0]},0.1],\"error\":1.0}";
|
||||
//! let remote_nc: NetworkCoordinate<3> = serde_json::from_str(received_msg).unwrap();
|
||||
//!
|
||||
//! // estimate the RTT to this remote node without measuring it directly
|
||||
//! let rtt_estimated = my_nc.estimated_rtt(&remote_nc);
|
||||
//!
|
||||
//! // so with just the knowledge of another NC, we can get reasonably good estimates of RTT
|
||||
//! // without actually needing to measure it
|
||||
//! ```
|
||||
//!
|
||||
|
||||
mod height_vector;
|
||||
mod vector;
|
||||
|
||||
// publish our interface
|
||||
pub mod network_coordinate;
|
||||
pub use network_coordinate::NetworkCoordinate;
|
||||
@@ -65,7 +65,7 @@ impl<const N: usize> NetworkCoordinate<N> {
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use vivaldi_nc::network_coordinate::NetworkCoordinate;
|
||||
/// use vivaldi_nc::NetworkCoordinate;
|
||||
///
|
||||
/// // create a new 3-dimensional random NC
|
||||
/// let a: NetworkCoordinate<3> = NetworkCoordinate::new();
|
||||
@@ -93,7 +93,7 @@ impl<const N: usize> NetworkCoordinate<N> {
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use vivaldi_nc::network_coordinate::NetworkCoordinate;
|
||||
/// use vivaldi_nc::NetworkCoordinate;
|
||||
///
|
||||
/// // create some 2-dimensional NCs for the sake of this example. These will just be random
|
||||
/// // NCs. In a real usecase these would have meaningful values.
|
||||
@@ -125,7 +125,7 @@ impl<const N: usize> NetworkCoordinate<N> {
|
||||
///
|
||||
/// ```
|
||||
/// use std::time::Duration;
|
||||
/// use vivaldi_nc::network_coordinate::NetworkCoordinate;
|
||||
/// use vivaldi_nc::NetworkCoordinate;
|
||||
///
|
||||
/// // We always have our own NC:
|
||||
/// let mut local: NetworkCoordinate<2> = NetworkCoordinate::new();
|
||||
|
||||
Reference in new issue
Block a user