Fix the NotNeeded warning

This commit is contained in:
Igor Katson 2023-11-19 20:01:08 +00:00
parent 2ad288199d
commit 3f0c4b7237
No known key found for this signature in database
GPG key ID: B4EC22B66D61A3F5

View file

@ -77,19 +77,23 @@ pub struct AggregatePeerStats {
impl PeerStates { impl PeerStates {
pub fn stats(&self) -> AggregatePeerStats { pub fn stats(&self) -> AggregatePeerStats {
self.states // TODO: it would be better to store these as atomic not to lock needlessly.
.iter() // However this would probably cause even more spaghetti.
.fold(AggregatePeerStats::default(), |mut s, p| { timeit("PeerStates::stats", || {
s.seen += 1; self.states
match &p.value().state { .iter()
PeerState::Connecting(_) => s.connecting += 1, .fold(AggregatePeerStats::default(), |mut s, p| {
PeerState::Live(_) => s.live += 1, s.seen += 1;
PeerState::Queued => s.queued += 1, match &p.value().state {
PeerState::Dead => s.dead += 1, PeerState::Connecting(_) => s.connecting += 1,
PeerState::NotNeeded => s.fully_have_and_we_are_finished += 1, PeerState::Live(_) => s.live += 1,
}; PeerState::Queued => s.queued += 1,
s PeerState::Dead => s.dead += 1,
}) PeerState::NotNeeded => s.fully_have_and_we_are_finished += 1,
};
s
})
})
} }
pub fn add_if_not_seen(&self, addr: SocketAddr) -> Option<PeerHandle> { pub fn add_if_not_seen(&self, addr: SocketAddr) -> Option<PeerHandle> {
use dashmap::mapref::entry::Entry; use dashmap::mapref::entry::Entry;
@ -293,6 +297,8 @@ pub struct TorrentState {
mod timed_existence { mod timed_existence {
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
pub struct TimedExistence<T>(T);
impl<T> TimedExistence<T> { impl<T> TimedExistence<T> {
#[inline(always)] #[inline(always)]
pub fn new(object: T, _reason: &'static str) -> Self { pub fn new(object: T, _reason: &'static str) -> Self {
@ -300,7 +306,6 @@ mod timed_existence {
} }
} }
pub struct TimedExistence<T>(T);
impl<T> Deref for TimedExistence<T> { impl<T> Deref for TimedExistence<T> {
type Target = T; type Target = T;
@ -316,6 +321,11 @@ mod timed_existence {
&mut self.0 &mut self.0
} }
} }
#[inline(always)]
pub fn timeit<R>(_name: &'static str, f: impl FnOnce() -> R) -> R {
f()
}
} }
#[cfg(feature = "timed_existence")] #[cfg(feature = "timed_existence")]
@ -324,6 +334,8 @@ mod timed_existence {
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
use tracing::warn; use tracing::warn;
const MAX: Duration = Duration::from_millis(5);
// Prints if the object exists for too long. // Prints if the object exists for too long.
// This is used to track long-lived locks for debugging. // This is used to track long-lived locks for debugging.
pub struct TimedExistence<T> { pub struct TimedExistence<T> {
@ -344,7 +356,6 @@ mod timed_existence {
impl<T> Drop for TimedExistence<T> { impl<T> Drop for TimedExistence<T> {
fn drop(&mut self) { fn drop(&mut self) {
const MAX: Duration = Duration::from_millis(1);
let elapsed = self.started.elapsed(); let elapsed = self.started.elapsed();
let reason = self.reason; let reason = self.reason;
if elapsed > MAX { if elapsed > MAX {
@ -366,9 +377,19 @@ mod timed_existence {
&mut self.object &mut self.object
} }
} }
pub fn timeit<R>(name: &'static str, f: impl FnOnce() -> R) -> R {
let now = Instant::now();
let r = f();
let elapsed = now.elapsed();
if elapsed > MAX {
warn!("elapsed on {name:?}: {elapsed:?}")
}
r
}
} }
pub use timed_existence::TimedExistence; pub use timed_existence::{timeit, TimedExistence};
impl TorrentState { impl TorrentState {
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
@ -645,7 +666,10 @@ impl TorrentState {
g.chunks.mark_chunk_request_cancelled(req.piece, req.chunk); g.chunks.mark_chunk_request_cancelled(req.piece, req.chunk);
} }
} }
s @ PeerState::Queued | s @ PeerState::Dead | s @ PeerState::NotNeeded => { PeerState::NotNeeded => {
return;
}
s @ PeerState::Queued | s @ PeerState::Dead => {
warn!("bug: peer was in a wrong state {s:?}, ignoring it forever"); warn!("bug: peer was in a wrong state {s:?}, ignoring it forever");
// Prevent deadlocks. // Prevent deadlocks.
drop(pe); drop(pe);
@ -654,11 +678,6 @@ impl TorrentState {
} }
}; };
// If peer is already set not needed, ignore.
if let PeerState::NotNeeded = pe.value().state {
return;
}
if error.is_none() { if error.is_none() {
debug!("peer died without errors, not re-queueing"); debug!("peer died without errors, not re-queueing");
pe.value_mut().state = PeerState::NotNeeded; pe.value_mut().state = PeerState::NotNeeded;