async_backtrace

This commit is contained in:
Igor Katson 2024-08-19 12:35:32 +01:00
parent 79e206d5a7
commit 7cda2c9807
No known key found for this signature in database
GPG key ID: B4EC22B66D61A3F5
5 changed files with 131 additions and 10 deletions

85
Cargo.lock generated
View file

@ -115,6 +115,33 @@ version = "1.0.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
[[package]]
name = "async-backtrace"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4dcb391558246d27a13f195c1e3a53eda422270fdd452bd57a5aa9c1da1bb198"
dependencies = [
"async-backtrace-attributes",
"dashmap",
"futures",
"loom",
"once_cell",
"pin-project-lite",
"rustc-hash 1.1.0",
"static_assertions",
]
[[package]]
name = "async-backtrace-attributes"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "affbba0d438add06462a0371997575927bc05052f7ec486e7a4ca405c956c3d7"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.74",
]
[[package]]
name = "async-recursion"
version = "1.1.1"
@ -963,6 +990,19 @@ dependencies = [
"slab",
]
[[package]]
name = "generator"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5cc16584ff22b460a382b7feec54b23d2908d858152e5739a120b949293bd74e"
dependencies = [
"cc",
"libc",
"log",
"rustversion",
"windows",
]
[[package]]
name = "generic-array"
version = "0.12.4"
@ -1467,6 +1507,7 @@ name = "librqbit"
version = "7.0.0-beta.0"
dependencies = [
"anyhow",
"async-backtrace",
"async-stream",
"async-trait",
"axum 0.7.5",
@ -1689,6 +1730,19 @@ version = "0.4.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
[[package]]
name = "loom"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5"
dependencies = [
"cfg-if",
"generator",
"scoped-tls",
"tracing",
"tracing-subscriber",
]
[[package]]
name = "lru"
version = "0.12.4"
@ -2203,7 +2257,7 @@ dependencies = [
"pin-project-lite",
"quinn-proto",
"quinn-udp",
"rustc-hash",
"rustc-hash 2.0.0",
"rustls",
"socket2",
"thiserror",
@ -2220,7 +2274,7 @@ dependencies = [
"bytes",
"rand",
"ring",
"rustc-hash",
"rustc-hash 2.0.0",
"rustls",
"slab",
"thiserror",
@ -2481,6 +2535,12 @@ version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
[[package]]
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "rustc-hash"
version = "2.0.0"
@ -2562,6 +2622,12 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "scoped-tls"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
[[package]]
name = "scopeguard"
version = "1.2.0"
@ -2992,6 +3058,12 @@ dependencies = [
"urlencoding",
]
[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "stringprep"
version = "0.1.5"
@ -3696,6 +3768,15 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f"
dependencies = [
"windows-targets 0.48.5",
]
[[package]]
name = "windows-core"
version = "0.52.0"

View file

@ -88,6 +88,7 @@ lru = { version = "0.12.3", optional = true }
mime_guess = { version = "2.0.5", default-features = false }
tokio-socks = "0.5.2"
async-trait = "0.1.81"
async-backtrace = "0.2"
[build-dependencies]
anyhow = "1"

View file

@ -14,7 +14,9 @@ use tracing::{error_span, info, Instrument};
use crate::{
create_torrent,
tests::test_util::{create_default_random_dir_with_torrents, TestPeerMetadata},
tests::test_util::{
create_default_random_dir_with_torrents, spawn_debug_server, TestPeerMetadata,
},
AddTorrentOptions, AddTorrentResponse, Session, SessionOptions,
};
@ -30,6 +32,8 @@ async fn test_e2e_download() {
async fn _test_e2e_download() {
let _ = tracing_subscriber::fmt::try_init();
spawn_debug_server();
// 1. Create a torrent
// Ideally (for a more complicated test) with N files, and at least N pieces that span 2 files.

View file

@ -1,8 +1,11 @@
use std::{io::Write, path::Path};
use anyhow::Context;
use axum::{response::IntoResponse, routing::get, Router};
use librqbit_core::Id20;
use rand::{thread_rng, Rng, RngCore, SeedableRng};
use tempfile::TempDir;
use tracing::info;
pub fn create_new_file_with_random_content(path: &Path, mut size: usize) {
let mut file = std::fs::OpenOptions::new()
@ -79,3 +82,28 @@ impl TestPeerMetadata {
0f64
}
}
async fn debug_server() -> anyhow::Result<()> {
async fn backtraces() -> impl IntoResponse {
async_backtrace::taskdump_tree(true)
}
let app = Router::new().route("/backtrace", get(backtraces));
let app = app.into_make_service();
let addr = "127.0.0.1:3032";
info!(%addr, "starting HTTP server");
use tokio::net::TcpListener;
let listener = TcpListener::bind(addr)
.await
.with_context(|| format!("error binding to {addr}"))?;
axum::serve(listener, app).await?;
Ok(())
}
pub fn spawn_debug_server() {
tokio::spawn(debug_server());
}

View file

@ -353,6 +353,7 @@ impl TorrentStateLive {
Ok(())
}
#[async_backtrace::framed]
async fn task_manage_incoming_peer(
self: Arc<Self>,
checked_peer: CheckedIncomingConnection,
@ -413,6 +414,7 @@ impl TorrentStateLive {
Ok(())
}
#[async_backtrace::framed]
async fn task_manage_outgoing_peer(
self: Arc<Self>,
addr: SocketAddr,
@ -449,12 +451,12 @@ impl TorrentStateLive {
state.meta.spawner,
state.meta.connector.clone(),
);
let requester = handler
let requester = async_backtrace::frame!(handler
.task_peer_chunk_requester()
.instrument(error_span!("chunk_requester"));
let conn_manager = peer_connection
.instrument(error_span!("chunk_requester")));
let conn_manager = async_backtrace::frame!(peer_connection
.manage_peer_outgoing(rx, state.have_broadcast_tx.subscribe())
.instrument(error_span!("peer_connection"));
.instrument(error_span!("peer_connection")));
handler
.counters
@ -1213,7 +1215,7 @@ impl PeerHandler {
}
loop {
self.wait_for_unchoke().await;
async_backtrace::frame!(self.wait_for_unchoke()).await;
if self.state.is_finished_and_dont_need_peers() {
debug!("nothing left to do, disconnecting peer");
@ -1232,7 +1234,7 @@ impl PeerHandler {
Some(next) => next,
None => {
debug!("no pieces to request");
tokio::time::sleep(Duration::from_secs(10)).await;
async_backtrace::frame!(tokio::time::sleep(Duration::from_secs(10))).await;
continue;
}
};
@ -1266,7 +1268,12 @@ impl PeerHandler {
};
loop {
match timeout(Duration::from_secs(10), self.requests_sem.acquire()).await {
match async_backtrace::frame!(timeout(
Duration::from_secs(10),
async_backtrace::frame!(self.requests_sem.acquire())
))
.await
{
Ok(acq) => break acq?.forget(),
Err(_) => continue,
};