# 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