Live data from Hacker News

Io_uring, kTLS and Rust for zero syscall HTTPS server

blog.habets.se

141–150 of 173 posts

Re: Io_uring, kTLS and Rust for zero syscall HTTPS server

#141

Earlier quoted context omitted.

One thread per core if you're CPU-bound and not IO-bound. In this very specific case, it seems as though the vast majority of the webserver's work is asynchronous and event-based, so the actual webserver is never waiting on I/O input or output - once it's ready you dump it somewhere the kernel can get to it and move on to the next request if there is one. I think this gets this specific project close to the platonic…

But, your CPU availability is time sliced... So, why is not "more than one thread per core" equivalent to "more CPU" (my point is, sometimes it is...)

https://github.com/rminnich/9front/tree/ron_nix

Has Ron Minnich's port of "Nix" (not NixOS as you may know it), to 9front.

The entire point of this is to disallow the kernel pre-empting and switching out CPU cores that should be dedicated to an "application". (Application Cores).

One could imagine this arrangement plus io_uring would be awfully nice.

Re: Io_uring, kTLS and Rust for zero syscall HTTPS server

#142

Earlier quoted context omitted.

genuinely so sad to me that you are still grinding this axe. if your fantasy design works so much better - go build it then!

Deal with it. Async is my greatest disappointment in the otherwise mostly stellar language. And I will continue to argue strongly against it. After Rust has raised the level of quality and expectations to such great level, async feels like 3 steps back with all those arguments "you are holding it wrong", footguns, and piles of hacks. And this sentiment is shared by many others. It's really disappointing to see how ma…

[dead]

Re: Io_uring, kTLS and Rust for zero syscall HTTPS server

#143
post #75

Unfortunately io_uring is disabled by default on most cloud workload orchestrators, like CloudRun, GKE, EKS and even local Docker. Hope this will change soon, but until then it will remain very niche.

Why do they disable io_uring?

Sandboxing like gvisor is based on syscalls and iouring makes your code syscallless

Re: Io_uring, kTLS and Rust for zero syscall HTTPS server

#144

Earlier quoted context omitted.

I mean from an outsiders perspective on Rust this is how I saw it. Rust is in a strange place because they're a systems language directly competing with C++. Async, in general, doesn't vibe with that but green threads definitely don't. If you're gonna do green threads you might as well throw in a GC too and get a whole runtime. And now you're writing Go.

I don't think doing green threads equates to 'well might as well have a GC now!'. I think they made the wrong tradeoff too, because hardware will inevitably catch up to the language requirements, especially if its desirable to use. Not to mention over time things can be made more efficient from the Rust side as well, with compiler improvements, better programming techniques etc. I think they made the wrong bet, perso…

There are other languages with green threads and folks are free to use those. Zig is trying to do interesting things with stackful coroutines.

I don't think I nor most systems programmers would have chosen rust if it required green threads instead of stackless coroutines for async. If you work on embedded or low level environments like kernels and whatnot, you need something that falls back to callbacks for async. I'm sure folks who work on servers would have been fine with green threads but they were not the target audience for rust. Being upset because you fall outside the target demographic of a particular language doesn't mean they made the wrong choice. It just means you should look for something else.

Re: Io_uring, kTLS and Rust for zero syscall HTTPS server

#145

Anybody know what the state of kTLS is? I asked one of the Cilium devs about it a while ago'cause I'd seen Thomas Graf excitedly talking about it and he told me that kernel support in many distros was lacking so they aren't ready to enable it by default.

kTLS just sounds like a bad idea all around.

Re: Io_uring, kTLS and Rust for zero syscall HTTPS server

#146
post #77

Earlier quoted context omitted.

Rust: Well yes. Rust does force you to understand the things, or it won't compile. It does have drawbacks. Go: goroutines are not async. And you can't understand goroutines without understanding channels. And channels are weirdly implemented in Go, where the semantics of edge cases, while well defined, are like rolling a D20 die if you try to reason from first principles. Go doesn't force you to understand things. I…

> Go: goroutines are not async Sure they are. The abstraction they provide is a synchronous API, but it's accomplished using an async runtime.

By that definition, pthread is also async. If everything is async, then the word loses all meanings.

Async is really about the surface syntax and ergonomics, not the implementation.

Re: Io_uring, kTLS and Rust for zero syscall HTTPS server

#147
post #32

Earlier quoted context omitted.

This can be done with exclusively owned objects. That's how io_uring abstractions work in Rust – you give your (heap allocated) buffer to a buffer pool, and get it back when the operation is done. &mut references are exclusive and non-copyable, so the hot potato approach can even be used within their scope. But the problem in Rust is that threads can unwind/exit at any time, invalidating buffers living on the stack,…

Yes and no. In my case, I have code that essentially looks like this: struct Parser { state: ParserState } struct Subparser { state: ParserState } impl Parser { pub fn parse_something(&mut self) -> Subparser { Subparse { state: self.state } // NOTE: doesn't work } } impl Drop for Subparser { fn drop(&mut self) { parser.state = self.state; // NOTE: really doesn't work } } Okay, I can make the first line work by changi…

You can implement this in Rust.

It's an equivalent of Rc>, Option>)>>, but with the Rc replaced by a custom shared type that avoids keeping refcount by having max 2 owners.

You're going to need UnsafeCell to implement the exact solution, which needs a few lines of code that is as safe as the C++ version.

Re: Io_uring, kTLS and Rust for zero syscall HTTPS server

#148

Earlier quoted context omitted.

This covers probably 90% of the usefulness of io_uring for non-niche applications. Its original purpose was doing buffered async file IO without a bunch of caveats that make it effectively useless. The biggest speed up I’ve found with it is ‘stat’ing large sets of files in the VFS cache. It can literally be 50x faster at that, since you can do 1000 files with a single systemcall and the data you need from the kernel…

For TCP streams syscall overhead isn't a big issue really, you can easily transfer large chunks of data in each write(). If you have TCP segmentation offload available you'll have no serious issues pushing 100gbit/s. Also if you are sending static content don't forget sendfile(). UDP is a whole another kettle of fish, get's very complicated to go above 10gbit/s or so. This is a big part of why QUIC really struggles t…

Yeah all agreed - the only addendum I’d add is for cases where you can’t use large buffers because you don’t have the data (e.g. realtime data streams or very short request/reply cycles). These end up having the same problems, but are not soluble by TCP or UDP segmentation offloads. This is where reduced syscall overhead (or even better kernel bypass) really shines for networking.

Re: Io_uring, kTLS and Rust for zero syscall HTTPS server

#149
post #37

I think rusts glacial compile times prevent it from being a useful platform for web apps. Yes it's a nice language, and very performant, but it's horrible devex to have to wait seconds for your server to recompile after a change.

> but it's horrible devex to have to wait seconds for your server to recompile after a change. What a time to be alived that seconds to recompile is consider horrible devex.

It was already horrible devex 40 years ago when turbo pascal could compile millions of lines almost instantly with a processor that was slower than my current watch processor.

Re: Io_uring, kTLS and Rust for zero syscall HTTPS server

#150

Earlier quoted context omitted.

It’s annoying but possible to do this correctly and not have the API be too bad. The “happy path” of a clean success or error is fine if you accept that buffers can’t just be simple &[u8] slices. Cancellation can be handled safely with something like the following API contract: Have your function signature be async fn read(buffer: &mut Vec ) -> Result ’ (you can use something more convenient like ‘&mut BytesMut’ too)…

It sounds like this would be better modelled by passing ownership of the buffer and expecting it to be returned on the success (ok) case. What you described doesn't seem compatible with what I would call a mutable borrow (mutate the contents of a Vec ). Or maybe I've misunderstood?

It is compatible under Rust’s model (I’ve used it to implement safe io_uring interfaces specifically). ‘&mut Vec’ doesn’t just let you mutate contents or extend the allocation - you can call ‘mem::replace(…)’ and swap the allocation entirely. It’s morally equivalent to passing back and forth, and almost identical in the generated machine code (structure return values look a lot like mutable structure arguments at the register calling convention level). However it’s much less annoying to work with in practice - passing buffers back and forth and then reassigning them to the same variable name results in a lot of semantically irrelevant code to please the ownership model.
Post reply on HN