# Microsoft Rust Training Team - Async Rust ## Metadata **Source**:: #from/zotero **Zettel**:: #zettel/fleeting **Status**:: #x **Authors**:: [[Microsoft Rust Training Team]] **Full Title**:: Async Rust **Category**:: #book **Date**:: [[2026]] **Created**:: [[2026-04-14]] **Document Tags**:: # **Zotero App Link**:: [Open in Zotero](zotero://select/library/items/DFVJT8LQ) **Zotero Web Link**:: [zotero.org](https://www.zotero.org/ianyi/items/DFVJT8LQ) # Annotations 2026-04-14 - Context β€” carries the Waker so the future can signal the executor when it’s ready to make progress [πŸ“„p. 19](zotero://open-pdf/library/items/JME9X3JN?page=25&annotation=LPLQWQMV) ^LPLQWQMV - The Waker is the callback mechanism. When a future returns Pending, it must arrange for waker.wake() to be called later β€” otherwise the executor will never poll it again and the program hangs. [πŸ“„p. 19](zotero://open-pdf/library/items/JME9X3JN?page=25&annotation=CGYE4JRU) ^CGYE4JRU - poll_fn: create a one-off future from a closure [πŸ“„p. 33](zotero://open-pdf/library/items/JME9X3JN?page=39&annotation=IZBI4ZUI) ^IZBI4ZUI - `yield_now`: voluntarily yield control to the executor. Useful in CPU-heavy async loops to avoid starving other tasks [πŸ“„p. 33](zotero://open-pdf/library/items/JME9X3JN?page=39&annotation=UAFL56LV) ^UAFL56LV - `Box::pin()` β€” heap-allocate and pin a future [πŸ“„p. 39](zotero://open-pdf/library/items/JME9X3JN?page=45&annotation=VZXQT9EH) ^VZXQT9EH - `tokio::pin!()` β€” pin a future on the stack [πŸ“„p. 39](zotero://open-pdf/library/items/JME9X3JN?page=45&annotation=V5CMBNXI) ^V5CMBNXI - Most types in Rust are Unpin β€” they don’t contain self-references, so pinning is a no-op. [πŸ“„p. 39](zotero://open-pdf/library/items/JME9X3JN?page=45&annotation=ZFQDIQPR) ^ZFQDIQPR - If you write a Future by hand and it has NO self-references, implement Unpin to make it easier to work with [πŸ“„p. 40](zotero://open-pdf/library/items/JME9X3JN?page=46&annotation=ZDPJLLDG) ^ZDPJLLDG - `Box::pin()` is the safe, easy way to pin `!Unpin` futures. `tokio::pin!()` pins on the stack but the future can’t be moved after. `Pin::new()` only works with Unpin types. [πŸ“„p. 42](zotero://open-pdf/library/items/JME9X3JN?page=48&annotation=N6XSHVGB) ^N6XSHVGB - ⚠ Don't stack-allocate huge buffers in async functions! Use `Vec<u8>` or `Box<[u8]>` instead. [πŸ“„p. 48](zotero://open-pdf/library/items/JME9X3JN?page=54&annotation=MNLHQHF9) ^MNLHQHF9 - IMPORTANT: Always update the waker. The executor may have changed it between polls [πŸ“„p. 55](zotero://open-pdf/library/items/JME9X3JN?page=61&annotation=9GJTFR8N) ^9GJTFR8N - When to use `io_uring`: High-throughput file I/O or networking where syscall overhead is the bottleneck (databases, storage engines, proxies serving 100k+ connections). For most applications, standard tokio with epoll is the right choice. [πŸ“„p. 72](zotero://open-pdf/library/items/JME9X3JN?page=78&annotation=9FGIL25T) ^9FGIL25T - embassy: Async for Embedded (`no_std`) [πŸ“„p. 74](zotero://open-pdf/library/items/JME9X3JN?page=80&annotation=9UETH5YP) ^9UETH5YP - Important: Dropping a JoinHandle does NOT cancel the task in tokio. The task becomes detached and keeps running. You must explicitly call .abort() to cancel it. This is different from dropping a Future directly, which does cancel/drop the underlying computation. [πŸ“„p. 85](zotero://open-pdf/library/items/JME9X3JN?page=91&annotation=89P4495J) ^89P4495J - The key principle: don’t use `std::sync::Mutex` across `.await` points. [πŸ“„p. 85](zotero://open-pdf/library/items/JME9X3JN?page=91&annotation=K6X8CW56) ^K6X8CW56 - Key takeaway: Semaphore is the standard way to limit concurrency in tokio. [πŸ“„p. 92](zotero://open-pdf/library/items/JME9X3JN?page=98&annotation=XMTHWPAY) ^XMTHWPAY - Use multi_thread for servers (default); current_thread for CLI tools, tests, or !Send types [πŸ“„p. 92](zotero://open-pdf/library/items/JME9X3JN?page=98&annotation=D3AYFYLK) ^D3AYFYLK - `let items = Arc::clone(&items);` [πŸ“„p. 95](zotero://open-pdf/library/items/JME9X3JN?page=101&annotation=NIEATVTT) ^NIEATVTT Clone the collection and get the item by index for each clone of the collection. - Rule of thumb: Libraries should depend on futures crate, not tokio. Applications should depend on tokio (or their chosen runtime). This keeps the ecosystem composable. [πŸ“„p. 99](zotero://open-pdf/library/items/JME9X3JN?page=105&annotation=A6XGI5AU) ^A6XGI5AU - The limitation: you can’t use `dyn DataStore` directly because the compiler doesn’t know the size of the returned future [πŸ“„p. 105](zotero://open-pdf/library/items/JME9X3JN?page=111&annotation=II3GXJUH) ^II3GXJUH - tokio-console gives you an htop-like view of every spawned task: its state, poll duration, waker activity, and resource usage. [πŸ“„p. 142](zotero://open-pdf/library/items/JME9X3JN?page=148&annotation=V5L2WV9U) ^V5L2WV9U - The tracing crate understands Future lifetimes. Spans stay open across `.await` points, giving you a logical call stack even when the OS thread has moved on [πŸ“„p. 143](zotero://open-pdf/library/items/JME9X3JN?page=149&annotation=SIDTEBS8) ^SIDTEBS8 - Tip: Enable `RUSTFLAGS="^--cfg tokio_unstable"` to get task-level metrics in tokio-console. This is a compile-time flag, not a runtime one. [πŸ“„p. 144](zotero://open-pdf/library/items/JME9X3JN?page=150&annotation=9X5JT8C7) ^9X5JT8C7 - JoinSet groups related tasks and ensures they all complete [πŸ“„p. 158](zotero://open-pdf/library/items/JME9X3JN?page=164&annotation=FQDTWZZZ) ^FQDTWZZZ - `tracker.close(); // No more tasks will be added` [πŸ“„p. 159](zotero://open-pdf/library/items/JME9X3JN?page=165&annotation=ZMJWNHCP) ^ZMJWNHCP - `tracker.wait().await; // Wait for ALL tracked tasks` [πŸ“„p. 159](zotero://open-pdf/library/items/JME9X3JN?page=165&annotation=HLS6SXFD) ^HLS6SXFD - Production tip β€” add jitter: The function above uses pure exponential backoff, but in production many clients failing simultaneously will all retry at the same intervals (thundering herd). Add random jitter β€” e.g., `sleep(delay + rand_jitter)` where `rand_jitter` is `0..delay/4` β€” so retries spread out over time. [πŸ“„p. 161](zotero://open-pdf/library/items/JME9X3JN?page=167&annotation=6UVDH3CD) ^6UVDH3CD - The error boundary problem β€” `tokio::spawn` erases context [πŸ“„p. 164](zotero://open-pdf/library/items/JME9X3JN?page=170&annotation=WDP9C9CM) ^WDP9C9CM