Right now the implementation of set_keepalive sets both the SO_KEEPALIVE and TCP_KEEPALIVE options, which may be unintuitive (doing two things at once). This behavior is just inherited from libuv and has not been scrutinized. Could this include some rationale as to why it should be stabilized this way?
Sure. Setting SO_KEEPALIVE will merely turn on that said socket should exhibit keepalive behavior. It will be set to use the default values provided by the OS. Passing the TCP_KEEPIDLE (TCP_KEEPALIVE on mac) option is need to adjust the timeout to something other than the default.
An implementation would be need to be added for Windows, setting SIO_KEEPALIVE_VALS, to do similarly on Windows.
It looks like the options for keepalive at the OS level take a seconds argument, but this RFC proposes taking a Duration. Can you clarify what it means to specify a fractional second? It would also be nice to clarify what it means to specify a 0-length duration.
The value is seconds on Linux, but it is milliseconds on Windows. For platforms that use seconds, the milliseconds could be truncated to the seconds place.
I couldn’t find anything specifically detailing when this value is 0. The Windows page puts the minimum value at 1, which is 1 millisecond.
So then, I’d suggest that passing Duration::zero() would turn off the keepalive feature, just as in the timeouts RFC.
How is is_closed implemented? I agree with @danburkert that this is a racy function to expose.
It didn’t sound like he meant the function itself is racy, just that trusting it could be. For example:
if !tcp.is_closed() {
// tcp could have been closed at this point
try!(tcp.read(buf));
}
In this case, that seems fine to me. I’d personally handle an ErrorKind::ConnectionAborted (or whichever it is) myself. I’d just rather be able to check that the stream is closed, such as in a ConnectionPool, before handing it out to be used. Once a timeout happens then, it can be a legitimate timeout.
Why take &mut self vs &self for set_keepalive? (the &mut isn’t required by the OS)
That was an oversight, I’m so used to setters taking &mut self. I just double checked the socket timeouts RFC, and it takes &self as well.