I definitely agree that I don’t want the existing structures to prevent the addition of new ones, but I definitely feel that TcpStream and the other types have their place (e.g. going to only Socket seems a bit extreme). There are indeed other socket types, however:
- Unix sockets on unix platforms
- Raw sockets (e.g. different protocol layers)
- A few other assorted kinds of sockets
Put another way the TcpStream type and friends definitely do not cover all possible sockets, so we’re losing out on a bit of possible interoperability with these other kinds of sockets. I personally see that as OK as the other kinds of sockets would likely also want their own standalone type to prevent mixing them up, and the semantics are so radically different that putting them all into one (when binding the FFI apis yourself isn’t so hard) may not be worth it at this time.
Two users that I’m aware of is @sfackler with unix-socket and @mrmonday with libpnet.
Making a nonblocking read should definitely be possible today, it’s just a matter of flipping the flag on the file descriptor. We don’t currently have a method for doing so, and for now I wanted to avoid adding this method until we have some more time to think through the async I/O story, but it’s also a pretty minor addition that could come in at any time (unstable of course).
I’m not quite sure what you mean by detecting the status of a socket, I would personally have to investigate the semantics of a 0-length read.
I was possibly thinking that one day we could have std::os::Socket so it’s at least in a separate location, but I was hoping to avoid it for now to stay conservative. I do think, though, that putting it in std::net (if we have builders) may be too confusing in the long haul.
Wow actually seeing that on paper definitely leads me to agree!
I’m somewhat hesitant to do this as it definitely detracts from “these are builders” as they’re really only builders-by-name at that point and don’t have any of the other ergonomic wins of builders elsewhere. For example the TcpBuilder basically wouldn’t follow any builder conventions!
Hm, this isn’t a bad idea. An important part about the API I wanted to preserve is precisely where an error happened (more on this below as well), but if we had a method to access the last error I think that may be ok.
The unfortunate part about this strategy is that you lose the knowledge about where the error happened. All our other builders don’t actually do any I/O operations until the very end, and it’s sometimes just one I/O operation, so the point of failure is always known. With TcpBuilder, however, each step is an I/O operation and precisely which one failed can sometimes be important.
@aturon was thinking we could possibly return some error payload information at the very end indicating which step failed, but I haven’t thought through this much and am somewhat skeptical how it may pan out.
I definitely agree with this! I suspect though that this may still be far enough out we may not be able to wait on it
Good idea!
Thanks for the comments everyone! I’ll have to think a bit on what to do about the builder aspect. I originally was going to propose std::net::Socket but the idea of a builder won me over, but this builder API definitely seems… unusual so far!