Merge pull request #34 from michel/issue-31-disconnect-state
fix(actor): leave Disconnected state behind after every disconnect
This commit is contained in:
@@ -658,6 +658,7 @@ impl PeerActor {
|
|||||||
debug!("[peer:{}] disconnect: {}", username, error);
|
debug!("[peer:{}] disconnect: {}", username, error);
|
||||||
|
|
||||||
self.stream.take();
|
self.stream.take();
|
||||||
|
self.connection_state = ConnectionState::Disconnected;
|
||||||
|
|
||||||
if self.disconnect_reported {
|
if self.disconnect_reported {
|
||||||
return;
|
return;
|
||||||
@@ -687,6 +688,7 @@ impl PeerActor {
|
|||||||
debug!("[peer:{}] disconnect", username);
|
debug!("[peer:{}] disconnect", username);
|
||||||
|
|
||||||
self.stream.take();
|
self.stream.take();
|
||||||
|
self.connection_state = ConnectionState::Disconnected;
|
||||||
|
|
||||||
if self.disconnect_reported {
|
if self.disconnect_reported {
|
||||||
return;
|
return;
|
||||||
@@ -927,21 +929,48 @@ mod tests {
|
|||||||
stream.set_nonblocking(true).unwrap();
|
stream.set_nonblocking(true).unwrap();
|
||||||
let (far_end, _) = listener.accept().unwrap();
|
let (far_end, _) = listener.accept().unwrap();
|
||||||
|
|
||||||
|
let (mut actor, rx) = make_actor(Some(stream));
|
||||||
|
actor.on_start();
|
||||||
|
(actor, rx, far_end)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn make_actor(
|
||||||
|
stream: Option<TcpStream>,
|
||||||
|
) -> (PeerActor, Receiver<ClientOperation>) {
|
||||||
let (tx, rx) = std::sync::mpsc::channel();
|
let (tx, rx) = std::sync::mpsc::channel();
|
||||||
let peer = Peer::new(
|
let peer = Peer::new(
|
||||||
"bob".to_string(),
|
"bob".to_string(),
|
||||||
ConnectionType::P,
|
ConnectionType::P,
|
||||||
"127.0.0.1".to_string(),
|
"127.0.0.1".to_string(),
|
||||||
u32::from(addr.port()),
|
0,
|
||||||
None,
|
None,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
let mut actor =
|
let actor = PeerActor::new(peer, stream, None, tx, "me".to_string(), 7);
|
||||||
PeerActor::new(peer, Some(stream), None, tx, "me".to_string(), 7);
|
(actor, rx)
|
||||||
actor.on_start();
|
}
|
||||||
(actor, rx, far_end)
|
|
||||||
|
#[test]
|
||||||
|
fn a_timed_out_connect_parks_the_actor_in_disconnected() {
|
||||||
|
let (mut actor, rx) = make_actor(None);
|
||||||
|
actor.connection_state = ConnectionState::Connecting {
|
||||||
|
since: Instant::now().checked_sub(Duration::from_secs(21)).unwrap(),
|
||||||
|
};
|
||||||
|
|
||||||
|
actor.tick();
|
||||||
|
|
||||||
|
assert!(
|
||||||
|
matches!(actor.connection_state, ConnectionState::Disconnected),
|
||||||
|
"a timed-out connect must leave Connecting"
|
||||||
|
);
|
||||||
|
match rx.try_recv() {
|
||||||
|
Ok(ClientOperation::PeerConnectFailed(7, username)) => {
|
||||||
|
assert_eq!(username, "bob");
|
||||||
|
}
|
||||||
|
other => panic!("expected PeerConnectFailed, got {other:?}"),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
@@ -834,7 +834,6 @@ impl ServerActor {
|
|||||||
closed by the server"
|
closed by the server"
|
||||||
);
|
);
|
||||||
self.session.record(SessionLoss::Displaced);
|
self.session.record(SessionLoss::Displaced);
|
||||||
self.connection_state = ConnectionState::Disconnected;
|
|
||||||
self.disconnect();
|
self.disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -845,8 +844,8 @@ impl ServerActor {
|
|||||||
// it, so anything still waiting on the network is waiting for good.
|
// it, so anything still waiting on the network is waiting for good.
|
||||||
if matches!(self.connection_state, ConnectionState::Connected) {
|
if matches!(self.connection_state, ConnectionState::Connected) {
|
||||||
self.session.record(SessionLoss::Disconnected);
|
self.session.record(SessionLoss::Disconnected);
|
||||||
self.connection_state = ConnectionState::Disconnected;
|
|
||||||
}
|
}
|
||||||
|
self.connection_state = ConnectionState::Disconnected;
|
||||||
self.stream.take();
|
self.stream.take();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -854,6 +853,7 @@ impl ServerActor {
|
|||||||
debug!("[server] disconnected");
|
debug!("[server] disconnected");
|
||||||
|
|
||||||
self.stream.take();
|
self.stream.take();
|
||||||
|
self.connection_state = ConnectionState::Disconnected;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_connection_status(&mut self) {
|
fn check_connection_status(&mut self) {
|
||||||
@@ -939,13 +939,35 @@ impl Actor for ServerActor {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::post_login_messages;
|
use super::*;
|
||||||
use crate::message::Message;
|
|
||||||
|
|
||||||
fn code_of(message: &Message) -> u32 {
|
fn code_of(message: &Message) -> u32 {
|
||||||
u32::from_le_bytes(message.get_data()[0..4].try_into().unwrap())
|
u32::from_le_bytes(message.get_data()[0..4].try_into().unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn a_timed_out_connect_parks_the_actor_in_disconnected() {
|
||||||
|
let (tx, _rx) = std::sync::mpsc::channel();
|
||||||
|
let mut actor = ServerActor::new(
|
||||||
|
PeerAddress::new("127.0.0.1".to_string(), 1),
|
||||||
|
tx,
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
actor.connection_state = ConnectionState::Connecting {
|
||||||
|
since: Instant::now().checked_sub(Duration::from_secs(21)).unwrap(),
|
||||||
|
};
|
||||||
|
|
||||||
|
actor.tick();
|
||||||
|
|
||||||
|
assert!(
|
||||||
|
matches!(actor.connection_state, ConnectionState::Disconnected),
|
||||||
|
"a timed-out connect must leave Connecting"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn post_login_messages_carry_counts_and_conditional_wait_port() {
|
fn post_login_messages_carry_counts_and_conditional_wait_port() {
|
||||||
let messages = post_login_messages(true, 4321, 3, 7);
|
let messages = post_login_messages(true, 4321, 3, 7);
|
||||||
|
|||||||
Reference in New Issue
Block a user