Is it bad behaviour for a Future or Stream to do something before being polled?

While code generally shouldn't expect a Future to do anything until polled, is it considered bad practice for implementors of Future to start background IO when they're constructed, rather than waiting until they're polled?

When I'm doing a disk write for example, I always want to start the operation right away, even if I'm not going to await() it until some future flushing event. I have Streams that behave this way, i.e. they kick off several readahead IOs as soon as they're constructed, so if someone constructs the Stream and then destroys it, it's more expensive than they might imagine.

This is basically a subjective question of whether this is considered a hacky thing to do, or perfectly normal. I guess the alternative would be to have my Stream/Future classes do nothing until polled, and put the onus on the caller to poke the futures (e.g. with now_or_never) after constructing them.

I can't think of anything technically wrong with doing so. The only problem is that it's surprising. What if someone constructs such future, and throws it away without polling it, expecting it to be cheap? It could happen in higher-level construct like select!, or let future = new(); if false { future.await }.

In normal operation you can expect futures to be polled pretty much immediately when they're spawned, so you're probably not saving much time (on the scale of time that I/O takes).

3 Likes

In tokio 0.1, functions like TcpStream::connect behaved as you describe (making I/O calls immediately, rather than waiting until the first poll). However, it looks like this has changed in tokio 0.2 and newer, as these methods became async fns.

2 Likes

For example I have a function which wraps a future to report its stat when its done including how long did it take. If the future do some heavy work before first poll, this function may need to take something like a closure returning future, which is not so trivial to make currently.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.