tokio-knowledge-patch
Tokio Knowledge Patch
Covers Tokio 1.46–1.50 (Jul 2025 – Mar 2026) and tokio-util 0.7.16–0.7.18 (Aug 2025 – Jan 2026). Claude Opus 4.6 knows Tokio through 1.45 and tokio-util through 0.7.15.
Index
| Topic | Reference | Key features |
|---|---|---|
| Task management | references/task-management.md | biased join, JoinSet::extend, JoinMap, JoinQueue |
| Synchronization | references/synchronization.md | SetOnce, Notify::notified_owned, CancellationToken adapters |
| Runtime & networking | references/runtime-and-networking.md | Cooperative scheduling APIs, is_rt_shutdown_err, set_zero_linger |
Quick Reference — New APIs by Crate
tokio (1.46–1.50)
| API | Version | What it does |
|---|---|---|
join!(biased; ...) / try_join!(biased; ...) |
1.46 | Poll branches in declaration order |
sync::SetOnce |
1.47 | Async OnceLock — set once, await from many tasks |
Notify::notified_owned() |
1.47 | Returns OwnedNotified (no lifetime) for use in spawned tasks |
task::coop::poll_proceed(cx) |
1.47 | Cooperative yielding in custom Future/Stream impls |
task::coop::cooperative(fut) |
1.47 | Wrap async block to opt into coop scheduling |
JoinSet::extend(iter) |
1.49 | Collect futures directly into a JoinSet |
TcpStream::set_zero_linger(bool) |
1.49 | Replaces deprecated set_linger |
runtime::is_rt_shutdown_err(&e) |
1.50 | Check if error is caused by runtime shutdown |
tokio-util (0.7.16–0.7.18)
| API | Version | What it does |
|---|---|---|
task::JoinMap<K, V> |
0.7.16 | Keyed JoinSet — associate a key with each spawned task |
task::JoinQueue |
0.7.17 | Like JoinSet but returns results in spawn (FIFO) order |
CancellationToken::unless_cancelled_with |
0.7.16 | Cancel futures directly with a token |
Deprecations & Migration
| Deprecated | Replacement | Version |
|---|---|---|
TcpStream::set_linger(Some(Duration::ZERO)) |
TcpStream::set_zero_linger(true) |
1.49 |
TcpSocket::set_linger(Some(Duration::ZERO)) |
TcpSocket::set_zero_linger(true) |
1.49 |
If you were calling set_linger(None) — just remove the call (OS default is no linger).
Essential Patterns (inline)
SetOnce — async one-time initialization
use tokio::sync::SetOnce;
static CONFIG: SetOnce<String> = SetOnce::const_new();
// First caller initializes; others wait then get the value
let val = CONFIG.get_or_init(|| async { load_config().await }).await;
// Non-blocking access after initialization
if let Some(cfg) = CONFIG.get() { /* already set */ }
JoinMap — keyed task set
use tokio_util::task::JoinMap;
let mut map = JoinMap::new();
map.spawn("fetch-users", async { fetch_users().await });
map.spawn("fetch-orders", async { fetch_orders().await });
while let Some((key, result)) = map.join_next().await {
println!("{key}: {result:?}");
}
JoinQueue — ordered task results
use tokio_util::task::JoinQueue;
let mut queue = JoinQueue::new();
queue.spawn(async { step_1().await });
queue.spawn(async { step_2().await });
// Results always in spawn order, regardless of completion order
while let Some(result) = queue.join_next().await {
process(result?);
}
Biased join! — deterministic poll order
// Polls in declaration order (like select!(biased; ...))
tokio::join!(biased; database_write, cache_invalidation, notification);
tokio::try_join!(biased; critical_op, secondary_op);
Cooperative scheduling in custom futures
use tokio::task::coop;
// In a Stream::poll_next or Future::poll implementation:
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Item>> {
let coop = ready!(coop::poll_proceed(cx)); // yields if budget exhausted
let item = self.produce_item();
coop.made_progress();
Poll::Ready(Some(item))
}
Runtime shutdown detection
match sender.send(msg).await {
Err(e) if tokio::runtime::is_rt_shutdown_err(&e) => {
// Runtime shutting down — clean exit
}
Err(e) => return Err(e.into()),
Ok(()) => {}
}
CancellationToken future adapters
use tokio_util::sync::CancellationToken;
let token = CancellationToken::new();
let result = my_future.unless_cancelled_with(&token).await;
// Either::Left(value) on completion, Either::Right(()) on cancellation
JoinSet vs JoinMap vs JoinQueue — when to use which
| Type | Crate | Result order | Keyed? | Use when |
|---|---|---|---|---|
JoinSet |
tokio | Completion order | No | Fire-and-forget concurrent tasks |
JoinMap<K, V> |
tokio-util | Completion order | Yes | Need to identify which task produced a result |
JoinQueue |
tokio-util | Spawn (FIFO) order | No | Results must be processed in submission order |
All three support spawn, spawn_on, join_next, abort_all, len, and is_empty.
Notify lifetime guide
| Method | Return type | Use when |
|---|---|---|
notify.notified() |
Notified<'_> |
Awaiting in the same scope |
notify.notified_owned() |
OwnedNotified |
Moving into tokio::spawn or storing in a struct |
More from nevaberry/nevaberry-plugins
dioxus-knowledge-patch
Dioxus changes since training cutoff (latest: 0.7.4) — Signals replacing use_state, RSX macro overhaul, server functions, asset!() system, dx CLI, Element-as-Result. Load before working with Dioxus.
46rust-knowledge-patch
Rust changes since training cutoff (latest: 1.94.0) \u2014 Rust 2024 Edition, async closures, trait upcasting, new std APIs, cargo resolver v3. Load before working with Rust.
20postgresql-knowledge-patch
PostgreSQL changes since training cutoff (latest: 18.1) — JSON_TABLE, SQL/JSON functions, MERGE RETURNING, virtual generated columns, UUIDv7, temporal PRIMARY KEY. Load before working with PostgreSQL.
16bun-knowledge-patch
Bun changes since training cutoff (latest: 1.3.10) \u2014 S3 client, built-in SQL/Redis, route-based HTTP server, CSS bundler, V8 compatibility. Load before working with Bun.
14nextjs-knowledge-patch
Next.js changes since training cutoff (latest: 16.1) — proxy.ts, \"use cache\", Cache Components, navigation hooks, typed routes, auto PageProps, React 19.2. Load before working with Next.js.
14postgis-knowledge-patch
PostGIS changes since training cutoff (latest: 3.6.1) — SFCGAL CG_* rename, ST_CoverageClean, ST_AsRasterAgg, topology bigint IDs, viewport simplification, 3D SFCGAL ops. Load before working with PostGIS.
13