# Blocking Call Audit > Audit the async Rust in a Tokio service before it ships - does it build with its tokio features, block a runtime worker, build futures that never run, drop its tasks, hold a std lock across an .await, or race a future that is not cancel safe - then fix it. The free check runs in the browser and uploads nothing: it lexes pasted Rust (one or more files, plus Cargo.toml for the tokio version and features), rebuilds its brace structure, resolves its use declarations, inventories every async fn, .await, spawned task and JoinHandle, blocking call, lock guard, channel and select!, and runs 17 deterministic checks drawn from Tokio practice. The paid audit rates the runtime, tasks, cancellation and resources, confirms or dismisses every flag and gives exact before/after edits per finding; the paid fix lane writes the whole fixed file(s) and a changes list tied to the flags. The page checks every quote and line against the paste, applies every edit and file back into the paste and re-runs its checks, and calls out a reply that repeats a credential from the paste. App: https://blocking-call-audit.skillsafe.ai/ API tutorial: https://blocking-call-audit.skillsafe.ai/api.html ## Input - The code pasted into one box, each file introduced by a `// file: ` line (`# file: Cargo.toml` for the manifest); dropped files or a dropped crate folder are joined that way automatically. A paste with no file line is read as one file (src/main.rs). - Nothing is compiled or run: every flag is a reading of the text, with the file and line it points at. Strings, raw strings, char literals and comments are lexed out first, so a string that mentions std::thread::sleep( is never a finding. `use` declarations are resolved, so a bare `sleep(` is known to be std's or tokio's. - Whether a function from another crate or module blocks or is async is outside the check (TK-18 says so); cargo build, cargo clippy and tokio-console stay the ground truth. ## Flags the free check raises - TK-01 (high): std::thread::sleep inside async code - the worker thread stops. - TK-02 (high): a blocking network call inside async code - reqwest::blocking (client or call), ureq, std::net TcpStream/UdpSocket/TcpListener, to_socket_addrs. - TK-03 (medium): a blocking std::process::Command output/status, a sync database call (rusqlite, postgres, sync diesel, redis get_connection), a std/crossbeam channel recv or a std thread join inside async code; one flag per fn with every line. - TK-04 (low): std::fs file I/O inside async code. - TK-05 (high): block_on (futures::executor, Runtime, Handle) or a new Runtime / runtime Builder inside async code. - TK-06 (high): a loop in async code that never awaits and never breaks, or that polls a flag or try_ call without awaiting. - TK-07 (high): a future built and dropped without .await - tokio::time::sleep/timeout, tokio::fs, a bounded tokio Sender::send, or an async fn of the paste called as a statement. - TK-08 (medium): a tokio::spawn / spawn_blocking whose JoinHandle is discarded or never used (a spawned async block that reports its own errors is exempt). - TK-09 (low): `let _ = fut.await;` or `fut.await.ok();` on a fallible call (sends, receives, sleeps and ticks are exempt). - TK-10 (low): tokio::spawn or JoinSet::spawn in a for loop over input, or join_all over a mapped iterator, with no Semaphore or buffer_unordered anywhere (a worker pool over a range is exempt). - TK-11 (high): a std::sync or parking_lot guard - bound with let, in an if let / while let / match scrutinee, or a temporary - still alive at an .await in the same task. - TK-12 (low): a tokio unbounded, std or crossbeam unbounded channel whose sender is fed in a loop. - TK-13 (medium): select! in a loop over read_line, read_exact, read_to_end, read_to_string, read_until, write_all or io::copy - directly or through an async fn of the paste (a pinned &mut future is exempt). - TK-14 (low): a tokio::spawn'd task running loop { } with no break, return, ?, select!, cancellation token or abort. - TK-15 (high): tokio features in Cargo.toml that miss what the code uses (#[tokio::main] needs macros and rt-multi-thread; tokio::time time; tokio::net net; io extension traits io-util; ...), or tokio used and not declared. - TK-16 (medium): a literal credential assigned to a secret-named const, let or field, or a literal Bearer header. - TK-17 (low): an async fn that never awaits (trait impls, main and tests are exempt). - TK-18 (info): context - counts, the tokio version and features, what is outside the check. ## Free extras - Every blocking call and every never-awaited future with the fn it is in; every spawned task with its kind, target and what happens to its JoinHandle; every lock guard and whether it is held across an .await; every channel with its kind and capacity; every select! with its branches and which are not cancel safe. - Put any audit finding (or all of them, or the fixed files) back into the paste and re-run the check; undo puts the original back. - Exports: the check as Markdown, the flags as CSV, the edited or fixed code, the findings or changes as CSV, the whole result as JSON. ## Paid lanes (the `task` field) - `audit`: `{task, verdict: blocked|needs_work|ready, headline, service, areas: [{area: runtime|tasks|cancellation|resources, status: sound|fragile|broken, note}], findings: [{id, flags, file, line, severity, area, title, evidence, why, edits: [{before, after}]}], flag_answers: [{flag, status: confirmed|dismissed, reason}], plan, questions, summary}`. `before` is an exact slice of the file, applied in order. - `fix`: `{task, verdict: fixed|partial, headline, files: [{path, content}], changes: [{file, function, flags, change, why}], verify, open: [{item, flags, reason}], questions, summary}`. `content` is the whole file (Cargo.toml included when a feature is missing); every fn keeps its name, parameters and fn or async fn. - Run input: `{task, code, facts, note?, audit_handoff?, retry_note?}` - all strings; `facts` is the page's analysis as a JSON string. The audit hands its findings to the fix lane with every edit applied to `code`. - Model: gpt-terra, 10% publisher markup. A run needs a signed-in account; the reservation shown before a run is a hold, and only what the run uses is charged. ## Sources - rust-async-patterns by Seth Hobson, wshobson/agents (github.com/wshobson/agents, plugins/systems-programming/skills/rust-async-patterns), MIT - https://skillsafe.ai/skill/@wshobson/rust-async-patterns - The checks and the reconciliation are original to this app. Rust is a trademark of the Rust Foundation; Blocking Call Audit is not affiliated with or endorsed by the Tokio project or the Rust Foundation.