rustybit_lib/
lib.rs

1#[macro_use]
2pub mod macros;
3pub mod parser;
4pub mod stats;
5pub mod torrent;
6pub mod torrent_meta;
7pub mod tracker;
8pub mod util;
9
10mod buffer;
11mod peer;
12mod peer_connection_manager;
13mod state;
14mod storage;
15
16pub use peer::handle_peer;
17pub use state::torrent::{Torrent, TorrentSharedState};
18pub use storage::{FileStorage, PieceHashVerifier, Storage, StorageManager, TorrentFileMetadata};
19
20use std::future::Future;
21use std::time::Duration;
22
23pub(crate) const DEFAULT_BLOCK_SIZE: u32 = 16_384;
24
25pub trait WithTimeout<T, E> {
26    fn with_timeout(
27        self,
28        name: &'static str,
29        timeout: Duration,
30    ) -> impl std::future::Future<Output = anyhow::Result<T>> + Send
31    where
32        Self: Future<Output = std::result::Result<T, E>>;
33}
34
35impl<F, T, E> WithTimeout<T, E> for F
36where
37    F: Future<Output = std::result::Result<T, E>> + Send,
38    anyhow::Error: From<E>,
39{
40    async fn with_timeout(self, name: &'static str, timeout: Duration) -> anyhow::Result<T> {
41        match tokio::time::timeout(timeout, self).await {
42            Ok(result) => Ok(result?),
43            Err(elapsed) => {
44                anyhow::bail!("'{}' task timed out: {}", name, elapsed);
45            }
46        }
47    }
48}
49
50pub trait Elapsed<T> {
51    fn with_elapsed(
52        self,
53        name: &'static str,
54        threshold: Option<Duration>,
55    ) -> impl std::future::Future<Output = T> + Send
56    where
57        Self: Future<Output = T>;
58}
59
60impl<F, T> Elapsed<T> for F
61where
62    F: Future<Output = T> + Send,
63{
64    async fn with_elapsed(self, name: &'static str, expected: Option<Duration>) -> T
65    where
66        Self: Future<Output = T>,
67    {
68        let start = std::time::Instant::now();
69        let result = self.await;
70
71        let elapsed = start.elapsed();
72        if expected.is_some_and(|expected| elapsed > expected) {
73            // SAFETY: checked above
74            tracing::trace!( expected = ?expected.unwrap(), ?elapsed, "'{}' task took more time than expected to execute", name);
75        } else {
76            tracing::trace!("'{}' task took {:?} to execute", name, elapsed);
77        }
78
79        result
80    }
81}