-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat!: distinguish peer and peer_id on api level #136
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,6 @@ | ||
use std::fmt::Debug; | ||
use std::hash::Hash; | ||
use std::net::SocketAddr; | ||
|
||
/// A remote peer. | ||
pub trait ConnectionPeer: Clone + Debug + Eq + Hash + PartialEq + Send + Sync {} | ||
|
||
impl ConnectionPeer for SocketAddr {} | ||
|
||
#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)] | ||
pub struct ConnectionId<P> { | ||
pub send: u16, | ||
pub recv: u16, | ||
pub peer: P, | ||
pub peer_id: P, | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
use std::fmt::Debug; | ||
use std::hash::Hash; | ||
use std::net::SocketAddr; | ||
|
||
/// A trait that describes remote peer | ||
pub trait ConnectionPeer: Debug + Clone + Send + Sync { | ||
type Id: Debug + Clone + PartialEq + Eq + Hash + Send + Sync; | ||
|
||
/// Returns peer's id | ||
fn id(&self) -> Self::Id; | ||
|
||
/// Consolidates two peers into one. | ||
/// | ||
/// It's possible that we have two instances that represent the same peer (equal `peer_id`), | ||
/// and we need to consolidate them into one. This can happen when [Peer]-s passed with | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Silly question: what does this syntax There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure if you are unsure about |
||
/// [UtpSocket::accept_with_cid](crate::socket::UtpSocket::accept_with_cid) or | ||
/// [UtpSocket::connect_with_cid](crate::socket::UtpSocket::connect_with_cid), and returned by | ||
/// [AsyncUdpSocket::recv_from](crate::udp::AsyncUdpSocket::recv_from) contain peers (not just | ||
/// `peer_id`). | ||
/// | ||
/// The structure implementing this trait can decide on the exact behavior. Some examples: | ||
/// - If structure is simple (i.e. two peers are the same iff all fields are the same), return | ||
/// either (see implementation for `SocketAddr`) | ||
/// - If we can determine which peer is newer (e.g. using timestamp or version field), return | ||
/// newer peer | ||
/// - If structure behaves more like a key-value map whose values don't change over time, | ||
/// merge key-value pairs from both instances into one | ||
/// | ||
/// Should panic if ids are not matching. | ||
fn consolidate(a: Self, b: Self) -> Self; | ||
} | ||
|
||
impl ConnectionPeer for SocketAddr { | ||
type Id = Self; | ||
|
||
fn id(&self) -> Self::Id { | ||
*self | ||
} | ||
|
||
fn consolidate(a: Self, b: Self) -> Self { | ||
assert!(a == b, "Consolidating non-equal peers"); | ||
a | ||
} | ||
} | ||
|
||
/// Structure that stores peer's id, and maybe peer as well. | ||
#[derive(Debug, Clone)] | ||
pub struct Peer<P: ConnectionPeer> { | ||
id: P::Id, | ||
peer: Option<P>, | ||
} | ||
|
||
impl<P: ConnectionPeer> Peer<P> { | ||
/// Creates new instance that stores peer | ||
pub fn new(peer: P) -> Self { | ||
Self { | ||
id: peer.id(), | ||
peer: Some(peer), | ||
} | ||
} | ||
|
||
/// Creates new instance that only stores peer's id | ||
pub fn new_id(peer_id: P::Id) -> Self { | ||
Self { | ||
id: peer_id, | ||
peer: None, | ||
} | ||
} | ||
|
||
/// Returns peer's id | ||
pub fn id(&self) -> &P::Id { | ||
&self.id | ||
} | ||
|
||
/// Returns optional reference to peer | ||
pub fn peer(&self) -> Option<&P> { | ||
self.peer.as_ref() | ||
} | ||
|
||
/// Consolidates given peer into `Self` whilst consuming it. | ||
/// | ||
/// See [ConnectionPeer::consolidate] for details. | ||
/// | ||
/// Panics if ids are not matching. | ||
pub fn consolidate(&mut self, other: Self) { | ||
assert!(self.id == other.id, "Consolidating with non-equal peer"); | ||
let Some(other_peer) = other.peer else { | ||
return; | ||
}; | ||
|
||
self.peer = match self.peer.take() { | ||
Some(peer) => Some(P::consolidate(peer, other_peer)), | ||
None => Some(other_peer), | ||
}; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it still valuable to see the
ConnectionPeer
embedded in thePeer
here? I imagine it could be, sometimes