async-executor
async-executor copied to clipboard
try_tick considered harmful
It is my current opinion that try_tick is almost never useful for the purposes that I've seen people use it.
The intended purpose is for FFI interop with other runtimes. Even then it's use case is niche. You almost never want to pop a task off of and not be notified of the next task later. In the worst cases it lends itself to creating a spin loop, where someone polls try_tick in a loop.
Even in the best cases the patterns that it creates are buggy. Here are issues caused by the misuse of the ticking APIs.
- https://github.com/orgs/smol-rs/discussions/298
- https://github.com/smol-rs/async-executor/issues/44
- No doubt constant misuses of this function in production code that is never reported.
For its intended use case of FFI interop, using tick() with a waker that wakes up the event loop that it's in is the preferred option. Even then run() would be the preferred option, as it runs forever.
My intention is as follows:
- Mark
try_tickas deprecated. - In the next breaking release of
async-executorremovetry_tick. - Specify in documentation that
runis the preferred way of driving the executor. - Specify in the documentation that
tickandtry_tickare exclusively used in executor interop, and that puresmoluse cases should userun().
I think try_tick is pretty useful to make an executor run statefully inside a non-async event loop like winit's.
I’m writing a simulation testing framework, and for that I need an executor that I can push forward in small steps, always bounded (assuming task computation between .await points is bounded). I looked at Tokio’s current-thread runtime, but it doesn’t allow me to run anything without waiting for a Future to complete. run() would have the same quality, so I’d be back to writing my own executor. Do I miss something?