Skip to content

Change the timeout API? #18

Closed
Closed
@ghost

Description

Timeouts are confusing. @spacejam recently wrote an example that contains the following piece of code:

stream
    .read_to_end(&mut buf)
    .timeout(Duration::from_secs(5))
    .await?;

The problem here is that we need two ?s after .await and it's easy to forget that.

I think the confusing part is in that the .timeout() combinator looks like it just transforms the future in a similar vein to .map() or .and_then(), but it really does not!

Instead, .timeout() bubbles the result of the future so that its type becomes Result<Result<_, io::Error>, TimeoutError>.

Perhaps it would be less confusing if timeout() was a free-standing function in the future module rather than a method on the time::Timeout extension trait?

future::timeout(
    stream.read_to_end(&mut buf),
    Duration::from_secs(5),
)
.await??;

This timeout() function would stand alongside ready(), pending(), and maybe some other convenience functions in the future module.

Here's another idea. What if we had io::timeout() function that resolves to a Result<_, io::Error> instead of bubbling the results? Then we could write the following with a single ?:

io::timeout(
    stream.read_to_end(&mut buf),
    Duration::from_secs(5),
)
.await?;

Now it's also more obvious that we're setting a timeout for an I/O operation and not for an arbitrary future.

In addition to that, perhaps we could delete the whole time module? I'm not really a fan of it because it looks nothing like std::time and I generally dislike extension traits like Timeout.

Note that we already have a time-related function, task::sleep(), which is not placed in the time module so we probably shouldn't worry about grouping everything time-related into the time module. I think it's okay if we have io::timeout() and future::timeout().

Finally, here's a really conservative proposal. Let's remove the whole time module and only have io::timeout(). A more generic function for timeouts can then be left for later design work. I think I prefer this option the most.

Metadata

Metadata

Assignees

No one assigned

    Labels

    api designOpen design questions

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions