Tokio bridge (id_effect_tokio)
The core id_effect crate defines interpreters (run_blocking, run_async, run_fork, …) and the Runtime trait. Workspace crate id_effect_tokio supplies the Tokio-backed implementation for binaries on #[tokio::main].
Read this section before Platform I/O, HTTP via reqwest, and Axum.
What id_effect_tokio provides
TokioRuntime— implements [id_effect::Runtime]: cooperative sleep/yield; forked fibers on Tokio's blocking pool.- Re-exports —
run_async,run_blocking,run_fork,yield_nowfor use at async boundaries. spawn_blocking_run_async— when the effect graph is notSendbut must be driven byrun_async(Axum uses the same pattern).
Capability DI with Tokio
Build Env manually or via run_with / build_env, then pass it to run_async:
use id_effect::{Env, caps, effect, require, run_async, succeed}; struct ApiToken; fn fetch() -> Effect<Vec<Quote>, AppError, caps!(ApiToken)> { effect!(|r| { let token = ~ApiToken; // async steps… Ok(quotes) }) } #[tokio::main] async fn main() { let mut env = Env::new(); env.insert::<Cap<ApiToken>>("secret"); let quotes = run_async(fetch(), env).await?; }
For provider-based apps, use build_env + run_async:
#![allow(unused)] fn main() { let env = build_env([provide!(ConfigLive), provide!(HttpClientLive)])?; let res = run_async(my_handler(), env).await?; }
Mental model
| Concern | Where it lives |
|---|---|
| Describing work | Effect<A, E, R> |
| Capabilities | caps!(…) + Needs<K> + run_with / build_env |
| Blocking / tests | run_blocking(effect, env) |
| Async I/O on Tokio | id_effect::run_async(effect, env) |
Sharp edges
Send:run_asyncfutures are often notSend— use Axum/Tower adapters orspawn_blocking_run_async.- Router tests: prefer
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]when exercising Axum + effects.
Further reading
- Example:
crates/id_effect_tokio/examples/109_tokio_end_to_end.rs cargo doc --open -p id_effect_tokio