Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upRFC: Expand the std::net module #1158
Conversation
alexcrichton
added
the
T-libs
label
Jun 11, 2015
alexcrichton
self-assigned this
Jun 11, 2015
alexcrichton
referenced this pull request
Jun 11, 2015
Closed
stabilize TcpStream::set_keepalive #1126
This comment has been minimized.
This comment has been minimized.
|
cc https://internals.rust-lang.org/t/pre-rfc-std-net-expansion-refinement/2079, some initial discussion |
sfackler
reviewed
Jun 11, 2015
| /// | ||
| /// This function directly corresponds to the bind(2) function on Windows | ||
| /// and Unix. | ||
| pub fn bind<T: ToSocketAddrs>(&self, addr: T) -> io::Result<&TcpBuilder>; |
This comment has been minimized.
This comment has been minimized.
sfackler
Jun 11, 2015
Member
It should probably be noted in the docs that using this in a builder-like fashion isn't possible in a non-painful fashion now (due to the io::Result wrapper), but may be in the future with something like ? sugar.
EDIT: ah, mentioned below
sfackler
reviewed
Jun 11, 2015
| the functions for now and will return `&Self` to enable chaining. | ||
|
|
||
| ```rust | ||
| pub fn foo(&self) -> io::Result<&Self>; |
This comment has been minimized.
This comment has been minimized.
sfackler
reviewed
Jun 11, 2015
| the specified `dur`. On Windows the implementation will start being wired up | ||
| to one call to modifying the `SIO_KEEPALIVE_VALS` option (this is | ||
| unimplemented today). This will be available on `TcpStream`. | ||
| * `read_timeout: Duration`, `write_timeout: Duration` - these are covered by |
This comment has been minimized.
This comment has been minimized.
llogiq
reviewed
Jun 16, 2015
| diagram, so this can be a natural conclusion to come to. | ||
|
|
||
| There are, however, not that many usages of typestate throughout the rest of the | ||
| standard library today, and there are a number of ergonomic and API concerns |
This comment has been minimized.
This comment has been minimized.
llogiq
Jun 16, 2015
Contributor
I think this may deserve a more specific treatment. What are the ergonomic and API concerns? Could they be somehow worked around?
Sockets have exceptional familiarity in network programming, so the motivation to choose a different option shouldn't be too hand-wavy.
This comment has been minimized.
This comment has been minimized.
alexcrichton
Jun 18, 2015
Author
Member
This was already a somewhat quite lengthy alternatives section, so I didn't want to dedicate too much text to this. It's also very difficult to say precisely what difficulties there are without talking about an exact API as there are multiple methods of representing typestate. Do you have a specific API in mind that you would like to see?
This comment has been minimized.
This comment has been minimized.
pythonesque
Jun 19, 2015
Contributor
FWIW, I'd be very interested to see what this would look like. Contrary to what you said about ergonomic and API concerns, I think that providing a C-like level of access with added type safety preventing misuse at compile time is entirely compatible with what Rust is aiming for. If the standard library doesn't use it much yet in public APIs, it's only because there hasn't been much need (where else do you envision it being useful that isn't already taken care of by destructors)? I also don't think we should worry overmuch about overlap with the existing interface; Java shipping nio didn't cause the end of the world, and it's still early enough to deprecate the old stuff.
This comment has been minimized.
This comment has been minimized.
seanmonstar
Jun 19, 2015
Contributor
Without designing the whole thing, but to give a peek, it could look something like this:
struct Socket<Type> {
// ...
}
enum Tcp {}
enum Udp {}
impl<T> Socket<T> {
// any socket has these methods
pub fn try_clone() {}
pub fn shutdown() {}
}
impl Socket<Tcp> {
pub fn accept(&mut self) -> io::Result<()> {
// ...
}
}Usage then could be:
let mut sock = Socket::<Udp>::connect(addr);
let other = sock.try_clone().unwrap();
sock.accept(); // compile error, Socket<Udp> does not have a method `accept`
This comment has been minimized.
This comment has been minimized.
alexcrichton
Jun 29, 2015
Author
Member
That form of typestate is actually basically equivalent to the TcpStream and UdpSocket distinction that we have today. It's unclear if you every really actually want to program with a Socket<T> vs a concrete Socket<Tcp> (e.g. Socket<T> can barely do anything).
llogiq
reviewed
Jun 16, 2015
| utilities, and there are clear cross-platform abstractions for building this | ||
| sort of functionality such as `select` and setting a socket to nonblocking mode. | ||
|
|
||
| This RFC does not, however, attempt to set forth a vision for nonblocking |
This comment has been minimized.
This comment has been minimized.
llogiq
Jun 16, 2015
Contributor
Pity that. I'd have thought this would be the first extension point of any std::net overhaul.
This comment has been minimized.
This comment has been minimized.
|
It seems like the right way forward here is a bit less clear than in other API proposals. Fortunately, I believe that the proposed APIs are implementable outside of libstd via Keeping it out of libstd will allow us to iterate more quickly, allow it to be used on the stable channel, and allow crates to use the functionality without bumping their minimum rustc version. I'm not sure if we'd also want to expose the API as unstable in libstd via similar trickery as liblibc, but my gut would say no for simplicity unless there's a compelling reason to. |
This comment has been minimized.
This comment has been minimized.
birkenfeld
commented
Jun 17, 2015
|
Is there a plan to add something like |
This comment has been minimized.
This comment has been minimized.
|
@sfackler: Agreed, incubating this out of tree will probably lead to better design in the long run. We may even have different implementations until a 'winner' emerges. |
RalfJung
reviewed
Jun 17, 2015
| to configure the default at a global level for Linux as well. Despite this, to | ||
| increase cross-platform interoperability, sockets created by `TcpListener::bind` | ||
| and `TcpStream::connect` will have this option set to `false` by default on *all | ||
| platforms*. |
This comment has been minimized.
This comment has been minimized.
RalfJung
Jun 17, 2015
Member
I have to say I find this worrisome. If I understand this paragraph properly, it says that Rust programs on Linux are going to actively ignore the default that an admin cared enough about to set it manually. I don't think admins will like this. Is there a precedent of another cross-platform language making a similar choice?
This comment has been minimized.
This comment has been minimized.
alexcrichton
Jun 18, 2015
Author
Member
It appears ruby does this by default at least, although there's definitely an interesting balance to draw here!
This comment has been minimized.
This comment has been minimized.
pythonesque
Jun 19, 2015
Contributor
Yeah, I find this worrisome as well. I do not think we should override defaults by default.
ayosec
reviewed
Jun 18, 2015
| pub enum WriteTimeout {} // SO_SNDTIMEO, Value = Option<Duration> | ||
| // tcp options | ||
| pub enum TcpNodelay {} // TCP_NODELAY, Value = bool |
This comment has been minimized.
This comment has been minimized.
ayosec
Jun 18, 2015
Can you add TCP_DEFER_ACCEPT?
http://linux.die.net/man/7/tcp:
TCP_DEFER_ACCEPT(since Linux 2.4)Allow a listener to be awakened only when data arrives on the socket. Takes an integer value (seconds), this can bound the maximum number of attempts TCP will make to complete the connection. This option should not be used in code intended to be portable.
This comment has been minimized.
This comment has been minimized.
alexcrichton
Jun 18, 2015
Author
Member
Certainly! This section, however, is just dedicated to outlining an alternative, but the standard platform-specific functionality we have in the rest of the standard library would allow binding this option from a std::os::linux::net extension trait.
nagisa
reviewed
Jun 18, 2015
| } | ||
| // socket options | ||
| pub enum Keepalive {} // SO_KEEPALIVE, Value = bool |
This comment has been minimized.
This comment has been minimized.
TheNeikos
referenced this pull request
Jun 18, 2015
Closed
Misleading example in the Docs regarding TcpListener #26395
This comment has been minimized.
This comment has been minimized.
TheNeikos
commented
Jun 18, 2015
|
With this proposal how would a timeout interact with (This is partly related to the above issue I closed as it could solve the problem I explained.) |
This comment has been minimized.
This comment has been minimized.
|
I don't believe any of this deals with support for |
This comment has been minimized.
This comment has been minimized.
TheNeikos
commented
Jun 18, 2015
|
If you set a timeout on a socket on which you accept it will return after that time of inactivity, at least that is what I read it out of the man pages. However, if I am wrong, which is quite possible, how would one then deal with the situation I showed? EDIT: I have now checked again(was on mobile before), and it seems that it should be possible. The man page in question. Although, if it is not possible I do not think that it is a good idea to go with a similar style as is present right now, that is with an iterator. Since there are only two ways to exit 'cleanly'.
|
This comment has been minimized.
This comment has been minimized.
I think prototyping this sort of functionality outside the standard library is a good idea, but I don't think that we should plan on leaving it out of the standard library indefinitely. This also I think extends the amount of time for this interface to become stable as once it's baked outside the standard library it'll also want to bake inside the standard library (as opposed to just baking inside for a bit). I'll try to make a prototype library in the near future though and see how it turns out.
At this time, no, but that's certainly a future extension!
@sfackler is correct in that this RFC doesn't add an option for that. Unfortunately I don't believe there's a socket option corresponding to the timeout on an accept operation, but if there is one we could certainly bind it! |
alexcrichton
referenced this pull request
Jun 25, 2015
Closed
Add TcpListener.bind_backlog to set tcp backlog #26551
This comment has been minimized.
This comment has been minimized.
seppo0010
commented
Jun 25, 2015
|
I like the proposal. I wonder if it would be possible and useful to break the API into traits, so people can support unix sockets easier receiving a generic type, e.g.: instead of |
alexcrichton
added
the
final-comment-period
label
Jul 1, 2015
This comment has been minimized.
This comment has been minimized.
|
This RFC is now entering its week-long final comment period. |
This comment has been minimized.
This comment has been minimized.
|
I'm on board, and would prefer if it was implemented out of libstd initially to allow for broader use and faster iteration. |
This comment has been minimized.
This comment has been minimized.
|
@sfackler, ah it slipped my mind but awhile back I implemented this RFC in the net2 crate on crates.io. To clarify, though, if this RFC is accepted would you want to hold off on the implementation in the standard library? |
This comment has been minimized.
This comment has been minimized.
|
Oh, nice. Not sure about merging it into std as well - we would have to decide what we want to do about synchronizing it with net2. Maybe add a note in the std docs to direct people towards net2 and sync them before releases? It could also be the case that the current setup works fine and we won't need to make many changes. |
This comment has been minimized.
This comment has been minimized.
|
The consensus of the libs team on this RFC is that the API is ok to merge, but we stalled out discussing what to do about whether this starts out as an external crate or in the standard library. We agreed on not having both of these as "officially maintained", so we just need to decide on one or another. As a results this RFC is going to remain in its final comment period for another week. |
This comment has been minimized.
This comment has been minimized.
muja
commented
Jul 21, 2015
|
Is there any plan to expose a local address option for a |
This comment has been minimized.
This comment has been minimized.
|
@muja Yes this should enable that by using |
This comment has been minimized.
This comment has been minimized.
seppo0010
commented
Jul 21, 2015
|
I don't know if my previous comment didn't make sense, so I'll insist I'd like to see the methods grouped into traits, because currently the way to reuse code in {Unix,Tcp}{Socket,Listener} is with macros, but generics would be nicer considering they are implementing the same API. Unless I'm missing something. |
This comment has been minimized.
This comment has been minimized.
|
@seppo0010 oh sorry I missed that! Adding traits to abstract over these is a backwards compatible addition and unix sockets also don't exist in the standard library today. Like with collections we prefer to start out with concrete interfaces and then leave the door open to adding a trait to be generic in the future. |
This comment has been minimized.
This comment has been minimized.
muja
commented
Jul 24, 2015
|
Would it make sense to not make any IO actions until the final call to let builder = TcpBuilder::new_v4();
builder.bind("192.168.0.1:0");
let conn1 = try!(builder.connect("http://rust-lang.org:80"));
let conn2 = try!(builder.connect("http://github.com:80"));Specifically this would be extremely useful in interplay with hyper, since it would allow using a The drawback obviously would be that more memory is needed and the errors will be delayed for the last step, but I think it's still worth it. Thoughts, opinions? |
This comment has been minimized.
This comment has been minimized.
|
@muja unfortunately I think the drawback of delaying errors makes it not worth it because the precise knowledge of where a chain of operations failed is often necessary. For example if |
This comment has been minimized.
This comment has been minimized.
muja
commented
Jul 24, 2015
|
@alexcrichton isn't it possible to have different Errors and return to see where it failed? |
This comment has been minimized.
This comment has been minimized.
|
It is, yes, but it can get pretty complicated pretty quickly. Plus if you only receive the error at the end you don't have the partial state you've built up so far. This means that in the case I described above, you'll actually create two sockets instead of one because the first is destroyed after the bind failed. |
This comment has been minimized.
This comment has been minimized.
muja
commented
Jul 24, 2015
|
Right, the 2-socket-argument makes sense. |
This comment has been minimized.
This comment has been minimized.
|
Unfortunately I don't think so because I believe the |
muja
referenced this pull request
Jul 25, 2015
Closed
feat(net): add net2 crate and TcpBuilderConnector #618
alexcrichton
added a commit
to alexcrichton/rust
that referenced
this pull request
Jul 28, 2015
alexcrichton
added a commit
to alexcrichton/rust
that referenced
this pull request
Jul 28, 2015
alexcrichton
referenced this pull request
Jul 28, 2015
Merged
std: Deprecate extra TcpStream/UdpSocket methods #27368
alexcrichton
added a commit
to alexcrichton/rust
that referenced
this pull request
Jul 28, 2015
bors
added a commit
to rust-lang/rust
that referenced
this pull request
Jul 29, 2015
aturon
removed
the
final-comment-period
label
Aug 7, 2015
This comment has been minimized.
This comment has been minimized.
|
This RFC is now re-entering its week-long final comment period. In light of #1242 merging recently my personal feelings are to close this without merging. Our new policy is to develop the crate in the rust-lang-nursery organization for some time and then RFC upon reentry into the standard library, so having an RFC here is a bit premature (but perhaps groundwork for a future one!) |
alexcrichton
closed this
Aug 27, 2015
alexcrichton
reopened this
Aug 27, 2015
This comment has been minimized.
This comment has been minimized.
|
er, didn't mean to close |
alexcrichton
added
the
final-comment-period
label
Aug 27, 2015
This comment has been minimized.
This comment has been minimized.
|
The libs team discussed this RFC during triage today, and the conclusion was that following the new rust-lang crates process we're going to close this and let the |
alexcrichton commentedJun 11, 2015
Expand the surface area of
std::netto bind more low-level interfaces andprovide more advanced customization and configuration of sockets.
Rendered