node: Handle `FetchOk` never being received
It's possible for a peer to disconnect before responding with `FetchOk`. In that case, we make sure to return to any pending fetch request with an error.
This commit is contained in:
parent
1168f2ddb5
commit
db38f2df76
|
|
@ -710,7 +710,16 @@ where
|
||||||
debug!(target: "service", "Disconnected from {} ({})", remote, reason);
|
debug!(target: "service", "Disconnected from {} ({})", remote, reason);
|
||||||
|
|
||||||
if let Some(session) = self.sessions.get_mut(&remote) {
|
if let Some(session) = self.sessions.get_mut(&remote) {
|
||||||
session.to_disconnected(since);
|
// If the peer disconnected while we were waiting for a [`Message::FetchOk`],
|
||||||
|
// return a failure to any potential fetcher.
|
||||||
|
if let Some(requested) = session.to_disconnected(since) {
|
||||||
|
if let Some(resp) = self.fetch_reqs.remove(&requested) {
|
||||||
|
resp.send(FetchResult::Failed {
|
||||||
|
reason: format!("disconnected: {reason}"),
|
||||||
|
})
|
||||||
|
.ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Attempt to re-connect to persistent peers.
|
// Attempt to re-connect to persistent peers.
|
||||||
if let Some(address) = self.config.peer(&remote) {
|
if let Some(address) = self.config.peer(&remote) {
|
||||||
|
|
@ -1484,7 +1493,7 @@ impl fmt::Display for DisconnectReason {
|
||||||
match self {
|
match self {
|
||||||
Self::Dial(err) => write!(f, "{err}"),
|
Self::Dial(err) => write!(f, "{err}"),
|
||||||
Self::Connection(err) => write!(f, "{err}"),
|
Self::Connection(err) => write!(f, "{err}"),
|
||||||
Self::Session(err) => write!(f, "error: {err}"),
|
Self::Session(err) => write!(f, "{err}"),
|
||||||
Self::Fetch(err) => write!(f, "fetch: {err}"),
|
Self::Fetch(err) => write!(f, "fetch: {err}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -292,8 +292,21 @@ impl Session {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_disconnected(&mut self, since: LocalTime) {
|
/// Move the session state to "disconnected". Returns any pending RID
|
||||||
|
/// that was requested.
|
||||||
|
pub fn to_disconnected(&mut self, since: LocalTime) -> Option<Id> {
|
||||||
|
let request = if let State::Connected {
|
||||||
|
protocol: Protocol::Gossip { requested },
|
||||||
|
..
|
||||||
|
} = self.state
|
||||||
|
{
|
||||||
|
requested
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
self.state = State::Disconnected { since };
|
self.state = State::Disconnected { since };
|
||||||
|
|
||||||
|
request
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ping(&mut self, reactor: &mut Reactor) -> Result<(), Error> {
|
pub fn ping(&mut self, reactor: &mut Reactor) -> Result<(), Error> {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue