Skip to content

Commit

Permalink
Add RestartConnect state; If one init method fails, the second can be…
Browse files Browse the repository at this point in the history
… used
  • Loading branch information
nieznanysprawiciel committed Jun 29, 2023
1 parent 0841b5d commit 0822fb7
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 6 deletions.
10 changes: 10 additions & 0 deletions client/src/_network_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,16 @@ impl NodeView {
Ok(())
}

pub async fn restart_initialization(&self) -> Result<(), TransitionError> {
{
let mut target = self.state.write().await;
target.state.transition(SessionState::RestartConnect)?;
}

self.notify_change(SessionState::RestartConnect);
Ok(())
}

pub async fn public_addresses(&self) -> Vec<SocketAddr> {
let target = self.state.read().await;
target.addresses.clone()
Expand Down
6 changes: 4 additions & 2 deletions client/src/_session_layer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -700,6 +700,7 @@ impl SessionLayer {
// We can still try other methods.
Err(SessionError::NotApplicable(e)) => {
log::debug!("Can't establish direct p2p session with [{node_id}]. {e}");
permit.registry.restart_initialization().await?;
}
// In case of other errors we probably shouldn't even try something else.
Err(e) => {
Expand All @@ -722,6 +723,7 @@ impl SessionLayer {
// We can still try other methods.
Err(SessionError::NotApplicable(e)) => {
log::debug!("Can't establish reverse p2p session with [{node_id}]. {e}");
permit.registry.restart_initialization().await?;
}
// In case of other errors we probably shouldn't even try something else.
Err(e) => {
Expand Down Expand Up @@ -1631,7 +1633,7 @@ mod tests {

layer2.capturer.captures.reverse_connection.drop_all();

// Function should return in timeout and return error.
// Function should finish in timeout and return error.
assert!(
timeout(Duration::from_millis(4500), layer1.layer.session(layer2.id))
.await
Expand All @@ -1653,7 +1655,7 @@ mod tests {
layer2.layer.server_session().await.unwrap();
layer2.capturer.captures.session_request.drop_all();

// Function should return in timeout and return error.
// Function should finish in timeout and return error.
assert!(
timeout(Duration::from_millis(3500), layer1.layer.session(layer2.id))
.await
Expand Down
26 changes: 22 additions & 4 deletions client/src/_session_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ pub enum SessionState {
/// Session was closed gracefully. (Still the reason
/// for closing could be some kind of failure)
Closed,
/// Current initialization method failed, but we could try other methods.
/// This state is equivalent of `ConnectIntent`, but moving to this state doesn't
/// give you `SessionPermit`.
RestartConnect,
}

#[derive(Clone, PartialEq, Display, Debug)]
Expand Down Expand Up @@ -166,13 +170,18 @@ impl SessionState {
SessionState::ReverseConnection(ReverseState::Awaiting),
) => true,
(
SessionState::Outgoing(InitState::ConnectIntent),
SessionState::Relayed(RelayedState::Initializing),
SessionState::RestartConnect,
SessionState::ReverseConnection(ReverseState::Awaiting),
) => true,
// We can establish Relayed connection if we made connect intent or we tried other methods
// that failed and we are in restating state.
(
SessionState::ReverseConnection(ReverseState::InProgress(InitState::ConnectIntent)),
SessionState::Outgoing(InitState::ConnectIntent),
SessionState::Relayed(RelayedState::Initializing),
) => true,
(SessionState::RestartConnect, SessionState::Relayed(RelayedState::Initializing)) => {
true
}
// We can start new session if it was closed, or if we failed to establish it previously.
(SessionState::Closed, SessionState::Outgoing(InitState::ConnectIntent)) => true,
(SessionState::Closed, SessionState::Incoming(InitState::ConnectIntent)) => true,
Expand All @@ -184,12 +193,21 @@ impl SessionState {
SessionState::FailedEstablish(_),
SessionState::Incoming(InitState::ConnectIntent),
) => true,
// If session is established, we don't want to block this transition to avoid unexpected
// behaviors. On the other side when in `Established` state, getting transition request
// to `Established` is already unexpected.
(SessionState::Established(_), SessionState::Established(_)) => true,
// In case of every initialization method we can retry using other method.
(SessionState::Relayed(_), SessionState::RestartConnect) => true,
(SessionState::Incoming(_), SessionState::RestartConnect) => true,
(SessionState::Outgoing(_), SessionState::RestartConnect) => true,
(SessionState::ReverseConnection(_), SessionState::RestartConnect) => true,
// We can attempt to make p2p connection, when previous initialization method failed.
(SessionState::RestartConnect, SessionState::Outgoing(InitState::Initializing)) => true,
// We can start closing only Established session. In other cases we want to make
// transition to `FailedEstablish` state.
(SessionState::Established(_), SessionState::Closing) => true,
(SessionState::Closing, SessionState::Closed) => true,

(SessionState::Incoming(prev), SessionState::Incoming(next)) => prev.allowed(next),
(SessionState::Outgoing(prev), SessionState::Outgoing(next)) => prev.allowed(next),
(SessionState::Relayed(prev), SessionState::Relayed(next)) => prev.allowed(next),
Expand Down

0 comments on commit 0822fb7

Please sign in to comment.