Skip to content

Tracking issue for the socket timeout functions #27773

Closed

Description

@alexcrichton

This is a tracking issue for the unstable socket_timeout feature in the standard library. Now that the Duration type is stable it may be the case that these methods can just be stabilized as-is.

Activity

  1. added
    T-libs-api[DEPRECATED; DO NOT USE]
    B-unstableBlocker: Implemented in the nightly compiler and unstable.
    on Aug 12, 2015
  2. alexcrichton commented on Aug 12, 2015

    @alexcrichton
    MemberAuthor
  3. added
    E-easyCall for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue.
    final-comment-periodIn the final comment period and will be merged soon unless new substantive objections are raised.
    on Aug 13, 2015
  4. alexcrichton commented on Aug 14, 2015

    @alexcrichton
    MemberAuthor

    This feature is now entering its final comment period for stabilization.

  5. seanmonstar commented on Aug 14, 2015

    @seanmonstar
    Contributor

    It was pointed out in a hyper issue that the returned error when a timeout is hit is OS dependent. It might be helpful to include a Errors subheading to the documentation of these methods?

    • Unixy returns ErrorKind::WouldBlock
    • Windows returns ErrorKind::TimedOut

    An alternative would be to normalize them into 1 type, but that seems more controversial.

  6. reem commented on Aug 14, 2015

    @reem
    Contributor

    I would like them to be normalized into one kind of error, not doing so will make code that uses these APIs non-cross-platform by default, which is very unfortunate IMO.

  7. eefriedman commented on Sep 3, 2015

    @eefriedman
    Contributor

    It's actually worse than the error codes just being inconsistent: on Windows, recv() returns WSAETIMEDOUT both when the receive call times out and when the connection itself times out, so you can't tell if the connection is still alive.

  8. droundy commented on Sep 3, 2015

    @droundy

    What does it mean for a socket itself to time out?

    On Thu, Sep 3, 2015, 4:38 AM eefriedman notifications@github.com wrote:

    It's actually worse than the error codes just being inconsistent: on
    Windows, recv() returns WSAETIMEDOUT both when the receive call times out
    and when the socket itself times out, so you can't tell if the socket is
    still alive.

    —
    Reply to this email directly or view it on GitHub
    #27773 (comment).

  9. eefriedman commented on Sep 3, 2015

    @eefriedman
    Contributor

    Err, sorry, I meant the connection, not the socket.

  10. sfackler commented on Sep 3, 2015

    @sfackler
    Member

    Is the connection timing out in reference to TCP keepalive or something?

  11. alexcrichton commented on Sep 3, 2015

    @alexcrichton
    MemberAuthor

    @seanmonstar, @reem, my personal inclination is to do what we do in the rest of std::io, which is to pass through exactly what the system does in as many places as possible. I've found that tampering with things like the error code and trying to unify them across platforms generally leads to weird corner cases which act differently than you may expect, so just reexposing what's happening underneath has worked quite well for us so far.

  12. eefriedman commented on Sep 3, 2015

    @eefriedman
    Contributor

    Is the connection timing out in reference to TCP keepalive or something?

    It's a bit more general than that: it means that the network stack closed the connection because it couldn't get a response from the other end. That doesn't necessarily mean a keepalive; it could also mean that it hit the general retransmission limit.

    @alexcrichton The problem here isn't precisely the portability of error codes; it's that recv() on Windows claims the connection is dead when it actually isn't. This means portable code must assume the connection is dead if the read timeout expires, so people will write code on Unix and find that there's no way to replicate the behavior on Windows without switching from std::net to some other networking library.

  13. aturon commented on Sep 9, 2015

    @aturon
    Contributor

    @alexcrichton

    my personal inclination is to do what we do in the rest of std::io, which is to pass through exactly what the system does in as many places as possible

    I'm not sure I agree with that characterization, though I know we had many debates about how to handle errors :-) In particular, though, we strove for cross-platform behavior wherever reasonable while also avoiding laying on extra semantics or overhead. Of course, the hard cases are when these constraints are at odds.

    From my perspective, if there's a reasonably clear way to merge or reinterpret errors so that they are consistent across platforms without information loss, I prefer doing so. The downside is that it's more difficult to map back to the underlying system error. (IIRC we ended up having a single mapping function from system errors to our IO errors, so what I'm suggesting is indeed somewhat of a departure.)

    Failing that, it's not too bad if there are multiple errors you might get depending on the platform, as long as there's a reasonable, robust way to program against them that doesn't require #[cfg].

    It's not clear whether we can achieve either of these, though, without layering on some extra checking/semantics on the Windows side -- but I haven't dug into the specifics too much.

    Can someone more familiar with the details propose an alternative that favors cross-platform semantics?

  14. eefriedman commented on Sep 9, 2015

    @eefriedman
    Contributor

    Alternative: don't use SO_RCVTIMEO or SO_SNDTIMEO because the semantics aren't portable. (Even if you ignore the Windows issues, the semantics are slightly different on Linux vs. *BSD.) Instead, use non-blocking sockets and select() to implement the intended functionality.

  15. aturon commented on Sep 11, 2015

    @aturon
    Contributor

    We discussed the issues in this thread fairly extensively in the last libs team meeting. The consensus was to follow the philosophy laid out in @alexcrichton's earlier comment: rather than trying to layer on additional semantics for cross-platform compatibility, we optimize for transparency, where IO functionality has a clear mapping to system APIs -- including errors. That means, in particular, sticking with a single global mapping of OS error codes to our IO error kinds.

    This strategy is contingent on clear documentation of platform-specific behavior, and the ability to provide additional layers, in std and elsewhere, that try to provide higher-level bridges between platforms. In particular, @sfackler suggested that the ErrorKind enum (or perhaps the Error type itself) could provide helper methods for deciphering errors in a context-specific and more cross-platform way. This provides an opt-in semantic layering over the raw system API. We plan to prototype this approach out of tree, and then consider bringing it into std.

  16. added a commit that references this issue on Sep 13, 2015
    f0b1326
  17. added a commit that references this issue on Sep 13, 2015
    cedbd99
  18. added this to the 1.3 milestone on Sep 18, 2015
  19. modified the milestones: 1.4, 1.3 on Oct 1, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    B-unstableBlocker: Implemented in the nightly compiler and unstable.E-easyCall for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue.T-libs-api[DEPRECATED; DO NOT USE]final-comment-periodIn the final comment period and will be merged soon unless new substantive objections are raised.

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions