I have production systems which run several 100k goroutines at once with very little overhead.
Thread-per-connection is the simplest way to do concurrent networking in Rust using only libstd, but it's not the way that most Rust programmers would actually use (at least, not for a production server handling a large number of connections).
Instead, we're layering platform-specific code in external libraries. At the raw C-level bindings, we have libc [2] and winapi [3]. For higher level APIs, we've got Mio [4] which abstracts the system APIs, and now Tokio [5], which uses futures to simplify async operations.
We're just working our way up the stack. All of these are being developed by members of the various Rust teams, so they're as "official" as everything else we're doing.
[1]: https://doc.rust-lang.org/std/net/ [2]: https://crates.io/crates/libc [3]: https://crates.io/crates/winapi [4]: https://github.com/carllerche/mio [5]: https://tokio.rs/
Goroutines are _very_ light (8KB stack size)
2kb, actually.If a goroutine calls into C, and the C code overflows or otherwise writes ‼Fun‼ onto the stack¹ … can it clobber an adjacent stack of another goroutine or other memory?
This is also true about OS threads!
Edit: Does "But that's true of Golang as well" refer to the one thread/socket model or not having epoll? I may have misinterpreted what you were saying...
(I know it's doable; I did it for a portscanner, where I needed fine grained timer control. But I had to forego the Go networking stack to do it.)
Seems pretty similar to me.
See this very very old HN thread:
https://news.ycombinator.com/item?id=3565703
(Hopefully the standard library has improved since then.)
(Early versions of Go had a "network channel" concept, but that was removed from the language: https://softwareengineering.stackexchange.com/questions/1540...)
It just happens to offer a similar model (and have a select operation).