Tokio integration for [id_effect]: [TokioRuntime] implements [id_effect::Runtime] with
cooperative sleep/yield, and runs forked effects on Tokio’s blocking thread pool via
[tokio::runtime::Handle::spawn_blocking] (the Effect interpreter is driven with
[run_blocking]; it is not Send for [tokio::spawn]).
Tower, Axum, and other Tokio-based adapters should depend on id_effect_tokio for this wiring.
Examples
See examples/ (e.g. 109_tokio_end_to_end). Import [run_async], [run_blocking],
run_fork, and [yield_now] from id_effect at the async boundary alongside [TokioRuntime].
Async effects that are not [Send] ([spawn_blocking_run_async])
[tokio::spawn] requires a [Send] future; the future produced by [run_async] often is not
[Send] (e.g. when the graph holds [id_effect::Scope] or [id_effect::Pool::get] checkout).
[Runtime::spawn_with] on [TokioRuntime] therefore drives the interpreter with [run_blocking],
which is wrong for effects that need a real async driver (I/O, timers). For those, use
[spawn_blocking_run_async] (or [TokioRuntime::spawn_blocking_run_async]): run the effect on
Tokio’s blocking pool and drive it with [run_async] inside [tokio::runtime::Handle::block_on] — the same
pattern as manually pairing [tokio::runtime::Handle::spawn_blocking] with block_on(run_async(..)).