[PITCH] io_uring support in Swift System on Linux

Yes, it was a recent revelation to me that polling can be more efficient than interrupts in some cases.

This is more meta level but this pitch is one of the first ones where we could use package traits. I was thinking about how we could integrate this into swift-nio while making sure that the APIs are working in practice. It is quite common that we need to do small tweaks to the API after integrating it and it getting the first production usage. One use-case for package traits is modeling experimental features across packages. We could put the new io_uring APIs behind an ExperimentalIOUring trait in swift-system. swift-nio could then redefine the same trait and conditionally enable swift-systems trait. This would give us some time to land the feature across the ecosystem and stabilize it before we have to fully commit to the API.

12 Likes

The other thing I would suggest is, should it be in Swift System if there’s no Darwin support?

Despite its name, Swift System has been designated the place for OS-specific APIs, not universal abstractions.

6 Likes

Right, though I'm somewhat confused by "despite its name". Swift System's purpose is to provide swift bindings for host system semantics. Hence, "Swift System". :grin:

4 Likes

I've pushed an update to the pitch with a number of changes discussed here. There's a few odds and ends I want to tie up before putting up a second pitch, but for anyone curious:

  • IOResource is a struct now, it turns out that works just as well; it doesn't fix the lifetime issues, but it's no worse than a class and better in other ways
  • "ing" names dropped
  • Cancellation operations added. I investigated the Rust versions of this, and I agree with them in principle, but I don't see a way to implement that sort of thing without being a very different type of API than we're currently proposing.
  • Features is an OptionSet now
  • Various smaller fixes like adding throws to a few operations that can fail

I have not, yet, addressed the following things I'm aware of from the thread that I'd like to get to before posting a new pitch, hopefully next week:

  • IORING_SETUP_SQPOLL, IOSQE_CQE_SKIP_SUCCESS, IORING_ATTACH_WQ, and other handy setup flags
  • Fleshing out the set of supported operations somewhat further
  • Perhaps some additional examples
  • Ideally, figuring out how to make the context/user_data system more ergonomic to use

I also haven't addressed, and don't plan to address (in this proposal) the tension between "expose io_uring in Swift", and "design a Swifty API for async IO, using io_uring". This proposal is the former, which automatically excludes a number of ideas that we might be able to do if we were more "opinionated" about how to use the underlying primitives.

I do want to take another glance over ringbahn and make sure I'm not missing something we can use, but so far what I'm seeing is more in the "opinionated abstraction" camp, albeit a very clever low overhead version of such.

9 Likes

Opinion question for y'all: I'm working on fleshing out the error handling story, and my initial approach was a couple of nested error structs for setup, resource registration, and operations… but I'm realizing that with an interface like this, throwing Errno might make just as much sense and be more consistent with other operations. Thoughts?

Also: after getting pulled away from this for a bit I'm back on it, and pretty much only blocked by a compiler crash I ran into that I'm still trying to find a workaround for.

Using Errno from swift-system makes sense to me and is what I did in IORingSwift.

1 Like

That's good to hear. Perhaps I can migrate IORingSwift to use your library.