Add NetStats
This commit is contained in:
parent
44122d77d6
commit
6794a683ce
@ -13,6 +13,7 @@ use crate::{
|
|||||||
PeerConfig, PeerMessage,
|
PeerConfig, PeerMessage,
|
||||||
listener::{DATAGRAM_SIZE, ListenerError},
|
listener::{DATAGRAM_SIZE, ListenerError},
|
||||||
package::{Message, Messages, Package},
|
package::{Message, Messages, Package},
|
||||||
|
stats::NetStats,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Represents an error during sending a package for any number of reason
|
/// Represents an error during sending a package for any number of reason
|
||||||
@ -97,7 +98,8 @@ impl<T: Clone + Serialize + DeserializeOwned + Send + Sync + 'static> Connection
|
|||||||
match conn.state {
|
match conn.state {
|
||||||
ConnectionState::ReceivingConnection | ConnectionState::Connecting => {
|
ConnectionState::ReceivingConnection | ConnectionState::Connecting => {
|
||||||
match self.udp.send_to(*addr, Package::<T>::Hello) {
|
match self.udp.send_to(*addr, Package::<T>::Hello) {
|
||||||
Ok(_) => {
|
Ok(bytes) => {
|
||||||
|
conn.bytes_tx += bytes;
|
||||||
conn.last_sent_ping = now;
|
conn.last_sent_ping = now;
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
@ -109,7 +111,8 @@ impl<T: Clone + Serialize + DeserializeOwned + Send + Sync + 'static> Connection
|
|||||||
}
|
}
|
||||||
ConnectionState::Connected | ConnectionState::ConnectingNearlyReady => {
|
ConnectionState::Connected | ConnectionState::ConnectingNearlyReady => {
|
||||||
match self.udp.send_to(*addr, Package::<T>::Ping) {
|
match self.udp.send_to(*addr, Package::<T>::Ping) {
|
||||||
Ok(_) => {
|
Ok(bytes) => {
|
||||||
|
conn.bytes_tx += bytes;
|
||||||
conn.last_sent_ping = now;
|
conn.last_sent_ping = now;
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
@ -121,7 +124,8 @@ impl<T: Clone + Serialize + DeserializeOwned + Send + Sync + 'static> Connection
|
|||||||
}
|
}
|
||||||
ConnectionState::Closing | ConnectionState::ReceivingClosing => {
|
ConnectionState::Closing | ConnectionState::ReceivingClosing => {
|
||||||
match self.udp.send_to(*addr, Package::<T>::Close) {
|
match self.udp.send_to(*addr, Package::<T>::Close) {
|
||||||
Ok(_) => {
|
Ok(bytes) => {
|
||||||
|
conn.bytes_tx += bytes;
|
||||||
conn.last_sent_ping = now;
|
conn.last_sent_ping = now;
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
@ -146,10 +150,13 @@ impl<T: Clone + Serialize + DeserializeOwned + Send + Sync + 'static> Connection
|
|||||||
ack: conn.ack,
|
ack: conn.ack,
|
||||||
reliable: conn.reliable_queue.clone(),
|
reliable: conn.reliable_queue.clone(),
|
||||||
unreliable: Vec::new(),
|
unreliable: Vec::new(),
|
||||||
|
messages_sent: conn.messages_sent,
|
||||||
};
|
};
|
||||||
match self.udp.send_to(*addr, Package::Messages(messages)) {
|
match self.udp.send_to(*addr, Package::Messages(messages)) {
|
||||||
Ok(_) => {
|
Ok(bytes) => {
|
||||||
|
conn.bytes_tx += bytes;
|
||||||
conn.last_msg_send = now;
|
conn.last_msg_send = now;
|
||||||
|
conn.messages_sent += 1;
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
conn.closing_since = Instant::now();
|
conn.closing_since = Instant::now();
|
||||||
@ -165,7 +172,10 @@ impl<T: Clone + Serialize + DeserializeOwned + Send + Sync + 'static> Connection
|
|||||||
if let Some(conn) = self.connections.get_mut(addr) {
|
if let Some(conn) = self.connections.get_mut(addr) {
|
||||||
if conn.state == ConnectionState::Connected {
|
if conn.state == ConnectionState::Connected {
|
||||||
let message_id = conn.message_counter;
|
let message_id = conn.message_counter;
|
||||||
conn.message_counter += 1;
|
if reliable {
|
||||||
|
// Only increment message counter for reliable messages
|
||||||
|
conn.message_counter += 1;
|
||||||
|
}
|
||||||
|
|
||||||
let message = Message {
|
let message = Message {
|
||||||
message_id,
|
message_id,
|
||||||
@ -185,10 +195,13 @@ impl<T: Clone + Serialize + DeserializeOwned + Send + Sync + 'static> Connection
|
|||||||
ack: conn.ack,
|
ack: conn.ack,
|
||||||
reliable: reliables,
|
reliable: reliables,
|
||||||
unreliable: unreliables,
|
unreliable: unreliables,
|
||||||
|
messages_sent: conn.messages_sent,
|
||||||
};
|
};
|
||||||
match self.udp.send_to(*addr, Package::Messages(messages)) {
|
match self.udp.send_to(*addr, Package::Messages(messages)) {
|
||||||
Ok(_) => {
|
Ok(bytes) => {
|
||||||
|
conn.bytes_tx += bytes;
|
||||||
conn.last_msg_send = Instant::now();
|
conn.last_msg_send = Instant::now();
|
||||||
|
conn.messages_sent += 1;
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
conn.closing_since = Instant::now();
|
conn.closing_since = Instant::now();
|
||||||
@ -227,7 +240,12 @@ impl<T: Clone + Serialize + DeserializeOwned + Send + Sync + 'static> Connection
|
|||||||
&mut self,
|
&mut self,
|
||||||
package: Package<T>,
|
package: Package<T>,
|
||||||
addr: &SocketAddr,
|
addr: &SocketAddr,
|
||||||
|
bytes: usize,
|
||||||
) -> Vec<PeerMessage<T>> {
|
) -> Vec<PeerMessage<T>> {
|
||||||
|
if let Some(conn) = self.connections.get_mut(addr) {
|
||||||
|
conn.bytes_rx += bytes;
|
||||||
|
}
|
||||||
|
|
||||||
let mut messages = Vec::new();
|
let mut messages = Vec::new();
|
||||||
|
|
||||||
match package {
|
match package {
|
||||||
@ -255,7 +273,9 @@ impl<T: Clone + Serialize + DeserializeOwned + Send + Sync + 'static> Connection
|
|||||||
if conn.state == ConnectionState::Connected {
|
if conn.state == ConnectionState::Connected {
|
||||||
conn.last_recv_ping = Instant::now();
|
conn.last_recv_ping = Instant::now();
|
||||||
match self.udp.send_to(*addr, Package::<T>::Pong) {
|
match self.udp.send_to(*addr, Package::<T>::Pong) {
|
||||||
Ok(_) => {}
|
Ok(bytes) => {
|
||||||
|
conn.bytes_tx += bytes;
|
||||||
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
conn.closing_since = Instant::now();
|
conn.closing_since = Instant::now();
|
||||||
conn.state = ConnectionState::Error;
|
conn.state = ConnectionState::Error;
|
||||||
@ -300,6 +320,11 @@ impl<T: Clone + Serialize + DeserializeOwned + Send + Sync + 'static> Connection
|
|||||||
}
|
}
|
||||||
Package::Messages(msgs) => {
|
Package::Messages(msgs) => {
|
||||||
if let Some(conn) = self.connections.get_mut(addr) {
|
if let Some(conn) = self.connections.get_mut(addr) {
|
||||||
|
// Store the expected number of messages to have received
|
||||||
|
// from the given connection
|
||||||
|
conn.messages_expected = msgs.messages_sent.max(conn.messages_expected);
|
||||||
|
conn.messages_received += 1;
|
||||||
|
|
||||||
// Clear all messages from the queue that the other peer has
|
// Clear all messages from the queue that the other peer has
|
||||||
// already seen
|
// already seen
|
||||||
conn.reliable_queue.retain(|v| v.message_id > msgs.ack);
|
conn.reliable_queue.retain(|v| v.message_id > msgs.ack);
|
||||||
@ -406,7 +431,7 @@ impl UdpWrapper {
|
|||||||
&self,
|
&self,
|
||||||
addr: SocketAddr,
|
addr: SocketAddr,
|
||||||
package: Package<T>,
|
package: Package<T>,
|
||||||
) -> Result<(), SendError> {
|
) -> Result<usize, SendError> {
|
||||||
if let Some(socket) = &self.socket {
|
if let Some(socket) = &self.socket {
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
let cursor = Cursor::new(&mut buf);
|
let cursor = Cursor::new(&mut buf);
|
||||||
@ -418,7 +443,7 @@ impl UdpWrapper {
|
|||||||
socket
|
socket
|
||||||
.send_to(&buf, addr)
|
.send_to(&buf, addr)
|
||||||
.map_err(|e| SendError::SendError(e))
|
.map_err(|e| SendError::SendError(e))
|
||||||
.map(|_| ())
|
.map(|_| buf.len())
|
||||||
} else {
|
} else {
|
||||||
Err(SendError::SocketDisconnected)
|
Err(SendError::SocketDisconnected)
|
||||||
}
|
}
|
||||||
@ -446,6 +471,13 @@ pub struct Connection<T: Clone> {
|
|||||||
/// What state is the connection currently in?
|
/// What state is the connection currently in?
|
||||||
pub state: ConnectionState,
|
pub state: ConnectionState,
|
||||||
error: Option<ConnectionError>,
|
error: Option<ConnectionError>,
|
||||||
|
|
||||||
|
// Stats
|
||||||
|
messages_sent: usize,
|
||||||
|
messages_received: usize,
|
||||||
|
messages_expected: usize,
|
||||||
|
bytes_tx: usize,
|
||||||
|
bytes_rx: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Clone> Clone for Connection<T> {
|
impl<T: Clone> Clone for Connection<T> {
|
||||||
@ -465,6 +497,13 @@ impl<T: Clone> Clone for Connection<T> {
|
|||||||
|
|
||||||
state: self.state.clone(),
|
state: self.state.clone(),
|
||||||
error: None,
|
error: None,
|
||||||
|
|
||||||
|
// Stats
|
||||||
|
messages_sent: self.messages_sent,
|
||||||
|
messages_received: self.messages_received,
|
||||||
|
messages_expected: self.messages_expected,
|
||||||
|
bytes_tx: self.bytes_tx,
|
||||||
|
bytes_rx: self.bytes_rx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -486,6 +525,21 @@ impl<T: Clone> Connection<T> {
|
|||||||
|
|
||||||
state,
|
state,
|
||||||
error: None,
|
error: None,
|
||||||
|
|
||||||
|
messages_sent: 0,
|
||||||
|
messages_received: 0,
|
||||||
|
messages_expected: 0,
|
||||||
|
bytes_tx: 0,
|
||||||
|
bytes_rx: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn statistics(&self) -> NetStats {
|
||||||
|
NetStats {
|
||||||
|
bytes_tx: self.bytes_tx,
|
||||||
|
bytes_rx: self.bytes_rx,
|
||||||
|
messages_received: self.messages_received,
|
||||||
|
messages_expected: self.messages_expected,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
24
src/lib.rs
24
src/lib.rs
@ -16,11 +16,13 @@ use thiserror::*;
|
|||||||
use crate::{
|
use crate::{
|
||||||
connections::{Connection, ConnectionError, ConnectionManager},
|
connections::{Connection, ConnectionError, ConnectionManager},
|
||||||
listener::{Listener, ListenerMessage},
|
listener::{Listener, ListenerMessage},
|
||||||
|
stats::NetStats,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub mod connections;
|
pub mod connections;
|
||||||
pub(crate) mod listener;
|
pub(crate) mod listener;
|
||||||
pub(crate) mod package;
|
pub(crate) mod package;
|
||||||
|
pub mod stats;
|
||||||
|
|
||||||
/// Error for the Peer
|
/// Error for the Peer
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
@ -169,9 +171,12 @@ impl<T: Clone + Serialize + DeserializeOwned + Send + Sync + 'static> Peer<T> {
|
|||||||
msg.is_some()
|
msg.is_some()
|
||||||
} {
|
} {
|
||||||
match msg.unwrap() {
|
match msg.unwrap() {
|
||||||
ListenerMessage::Package(package, socket_addr) => {
|
ListenerMessage::Package(package, socket_addr, bytes) => {
|
||||||
self.messages
|
self.messages.extend(self.connection_mgr.handle_package(
|
||||||
.extend(self.connection_mgr.handle_package(package, &socket_addr));
|
package,
|
||||||
|
&socket_addr,
|
||||||
|
bytes,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
ListenerMessage::PackageError(listener_error, socket_addr) => {
|
ListenerMessage::PackageError(listener_error, socket_addr) => {
|
||||||
println!("Error: {}", listener_error);
|
println!("Error: {}", listener_error);
|
||||||
@ -232,4 +237,17 @@ impl<T: Clone + Serialize + DeserializeOwned + Send + Sync + 'static> Peer<T> {
|
|||||||
pub fn connections(&self) -> Vec<Connection<T>> {
|
pub fn connections(&self) -> Vec<Connection<T>> {
|
||||||
self.connection_mgr.connections()
|
self.connection_mgr.connections()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn statistics(&self) -> NetStats {
|
||||||
|
let conns = self.connection_mgr.connections();
|
||||||
|
let all_stats = conns.iter().map(|c| c.statistics());
|
||||||
|
let mut total_stats = NetStats::default();
|
||||||
|
for stats in all_stats {
|
||||||
|
total_stats.bytes_rx += stats.bytes_rx;
|
||||||
|
total_stats.bytes_tx += stats.bytes_tx;
|
||||||
|
total_stats.messages_expected += stats.messages_expected;
|
||||||
|
total_stats.messages_received += stats.messages_received;
|
||||||
|
}
|
||||||
|
total_stats
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -39,7 +39,9 @@ impl<'a, T: Clone + Serialize + DeserializeOwned> Listener<T> {
|
|||||||
let res =
|
let res =
|
||||||
ciborium::from_reader_with_buffer::<Package<T>, _>(bytes, &mut ciborium_buf);
|
ciborium::from_reader_with_buffer::<Package<T>, _>(bytes, &mut ciborium_buf);
|
||||||
match res {
|
match res {
|
||||||
Ok(pkg) => self.sender.send(ListenerMessage::Package(pkg, from_addr)),
|
Ok(pkg) => self
|
||||||
|
.sender
|
||||||
|
.send(ListenerMessage::Package(pkg, from_addr, num_bytes)),
|
||||||
Err(_) => self.sender.send(ListenerMessage::PackageError(
|
Err(_) => self.sender.send(ListenerMessage::PackageError(
|
||||||
ListenerError::ParseError,
|
ListenerError::ParseError,
|
||||||
from_addr,
|
from_addr,
|
||||||
@ -61,7 +63,7 @@ pub enum ListenerError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub enum ListenerMessage<T: Clone + Serialize + DeserializeOwned> {
|
pub enum ListenerMessage<T: Clone + Serialize + DeserializeOwned> {
|
||||||
Package(Package<T>, SocketAddr),
|
Package(Package<T>, SocketAddr, usize),
|
||||||
PackageError(ListenerError, SocketAddr),
|
PackageError(ListenerError, SocketAddr),
|
||||||
Error(std::io::Error),
|
Error(std::io::Error),
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,6 +12,7 @@ pub enum Package<T> {
|
|||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct Messages<T> {
|
pub struct Messages<T> {
|
||||||
pub ack: u64,
|
pub ack: u64,
|
||||||
|
pub messages_sent: usize,
|
||||||
pub reliable: Vec<Message<T>>,
|
pub reliable: Vec<Message<T>>,
|
||||||
pub unreliable: Vec<Message<T>>,
|
pub unreliable: Vec<Message<T>>,
|
||||||
}
|
}
|
||||||
|
|||||||
7
src/stats.rs
Normal file
7
src/stats.rs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#[derive(Default)]
|
||||||
|
pub struct NetStats {
|
||||||
|
pub bytes_tx: usize,
|
||||||
|
pub bytes_rx: usize,
|
||||||
|
pub messages_received: usize,
|
||||||
|
pub messages_expected: usize,
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user