OCaml 5 itself is fine (the concept of domain aside). But the ecosystem went from {lwt,async} to {lwt,async,abb,eio,miou,moonpool,…}. So the problematic fragmentation has become much, much worse. I’m glad io_uring is working for you but it’s not the issue, the issue is the absence of shared/standard fundamental concurrency building blocks, and of a shared abstraction for a swappable concurrency runtime. Right now you have to fully buy-in into one of these shards of ecosystem, from promise to http library.
Ok I’ve always been silent, but now I’ll add this, io_uring was never necessary, it’s just some cool stuff that people want to play with, it might be “mildly” useful once you’ve worked out all the bottlenecks and everything is super efficient, also the bindings was very deficient.
In my very humble opinion, as someone who doesn’t understand when you speak in weird FP terms(but who also built very serious parallel stuff), it seems to me that:
The struggle of this community has always been separating what is “cool” than what is “useful”.
If you want to start a discussion of why io_uring is not necessary, I’ll use the same argument people used for EIO, when they said they wanted to be more like “go”, the netpoller in Go doesn’t use it (to this day), in fact most runtimes don’t use it, and if they do, it’s for files only, because it’s a fucking mess, it’s buggy, it depends on weird file descriptor semantics, and guess what? The bottleneck has never been that (don’t come showing a cp(1) benchmark, please). Yet resources were diverted to it, and money was spent.
People had grudges with EIO since day one, including me, who was on the EIO team, a considerable number of people knew it wouldn’t fly, yet I’m here 4 years later (after we lost how many people to this?), reading that finally there is some realization.
Notice how I’m not even talking about capabilities, or that fact that you would double copy things in a temporary buffer, or hold megabytes of buffers because the backpressure was all wrong. Or how it conflated SOCK_STREAM with SOCK_DGRAM, or how you couldn’t have an atomic select (which is kinda the basic of all modern concurrency thing in go).
Having said that, this was all prior to @Vincent_Balat involvement and I genuinely think he is one of the coolest people in this community, and I respect him dearly.
And one notable omission on that list is Picos, - coming from a purely hardware-based, synthesis context, which is directly related to software composition, you always build with primatives
Oh I wish picos had been adopted as a foundation for all that, but it didn’t and now it’s a dead project (I think I’m the only user remaining). ![]()
No, you’re not! It’s the basis of all of my kernels
Yes I agree with that. However, this strikes me as fundamental research and not something for which there is a good, known answer yet. I’ve seen numerous PLDI/ICFP/POPL papers fly past in recent years (formalising the Eio core, the OxCaml modes, lots of systems ones on better use of hardware), and I’m looking forward to this year’s ICFP as well where more are set to appear. This forum is not entirely representative of the wider contributions that are ongoing from many people.
You describe the history of Linux here, not just io_uring
I used to have the same attitude as you back in the Xen days, and I feel we got thoroughly left behind by just how relentlessly Linux improves a initially bad subsystem like KVM over the years. See also how FUSE performance has increased in the past decade. And virtio…
Io_uring was terribad three years ago, and now it’s just bad when multitenant, and it looks set to get better with features like eBPF integration, and it’ll no doubt improve more as cooperative scheduling patches (like Ghost) land. So yes, this is a bet, and I think a useful contribution to the Linux ecosystem to try it. Noone’s forcing anyone to use it; the Eio_posix subsystem is fully functional and often necessary for missing functionality or if running in seccomp environments like Docker that block uring syscalls by default.
These are legitimate concerns and, as such, it is above all a matter of acknowledging the efforts that have been made in this direction, efforts which have not necessarily been successful but which do point to possibilities. In this regard, our cooperative has already established that, as far as the implementation of protocols and formats is concerned, these are always independent of any scheduler (as has been the case since ocaml-tls, see this paper). In this sense, our cooperative has always ensured that our work remains fully reusable by others who do not use our Miou scheduler (this is also very similar to initiatives that have since emerged, such as the sans-io movement).
I would also like to emphasise that attempts have been made to align with picos (which, to my knowledge, has not been done with regard to eio). However, we would like such approaches to take place within a framework that respects the CoC (thereby avoiding insults and defamation, which we have unfortunately had to face).
If such a framework exists and if people wish to build on what has already been done here and here (and thus formally agree on Trigger and Computation), we have no problem devoting our energy to this matter.
As far as we (the members of the MirageOS core team) are concerned, the Eio team has never included us in any discussions aimed at reaching agreement on the possibility of creating unikernels with this scheduler. And although some people wear several hats in this matter, Eio has never reached a consensus within the MirageOS core team (whether on task management policy or on the issue of capabilities). It seems there is no consensus within the community either.
Miou then came along, and I can confirm that it is now possible to develop proper unikernels (even a website) using it without too much difficulty (see our tutorial).
This topic is interesting because I really see it as a re-emergence of what has been criticised on several occasions regarding Eio, and above all it highlights an inability on the part of those involved to collaborate beyond the confines of their own companies. Other actors are therefore turning to developing their own solutions or use what it already exists, having failed to find anything close to what they’re hoping for in Eio. Perhaps it’s time to accept the criticism (whether technical or interpersonal).
I do not know if it constitutes an attempt to align with picos, but I spent some time and effort porting the core of eio to picos and posted about it in on this topic’s counterpart over a year ago:
I think there would not be too many blockers with the right amount of effort (maybe that is naive). Perhaps this is a viable way forward for shared concurrency primitives? It seems to me that each of the direct-style schedulers cater to quite different audiences:
- Eio is capability-based and opts for an explicit structured concurrency.
- Miou (correct me if I am wrong) cares a lot about availability in its design and scheduling.
- Moonpool is geared towards CPU-bound workloads that need parallelisation.
Which is great! And if we go the san-io approach (and the bytesrw approach) then all we have to agree on is how to store our bytes
!
I think it’d be great to have these (they’re basically a port of picos, right? trigger, computation, probably a couple of await/yield effects). But it’s still too late.
If Eio doesn’t adopt the building blocks, the fragmentation will still be problematic. And the Eio team hasn’t shown much interest in interoperability within the ecosystem. The opinionated choices that were baked in lead to multiple long discussions where people expressed pushback against these decisions.
it’s hardly selective: i removed the parenthetic content (an aside or a minor clarification),
maybe if the intention is to explain that the runloop is incompatible with existing concurrency library then that’s what should be written?
[dusts off my old technical writer hat, secures it solidly on my head] readers are more likely to interpret literally the direct simple sentences and stretch the interpretation of passive more complex sentences. make your point explicitly. anyway, looking forward to the amended readme.
Yes! A parallel thread in eio#879 delivered the same result, so that’s merged.
Pulling this back to the original topic, my main worry isn’t runloop composition, but rather that multiple libraries using effects are difficult to use together in practise due to the ordering of the handlers. An ‘effect registration’ library a bit like ppxlib might be helpful to let the community coordinate a collection of known ones published to opam.
For that reason, Ocsigen sticking to Lwt seems to me to be the best option right now, at least until wasm stack switching matures sufficiently that there’s no runtime cost to using effects on the web.
I agree strongly with this, and the point that the different schedulers have different goals, so it’s great to have all of them around. Adding Picos to Eio doesn’t seem too bad, and at some point we’ll do the big switch to bytes in Eio. Not having to choose between Bigarray and bytes for IO might actually be the actual biggest win from OCaml 5 ![]()
That was not really my point, it’s not about quality, being bad just makes it even worse
.
If io_uring was perfect in 2022, it would still do nothing for the success or adoption of the project, in fact it’s negative since you buy bugs, a whole chunk of code, and have to spend developer time on it, it’s just noise and it makes people switch their attention from what it really matters.
My gripe is that io_uring is thrown out as if it did something for someone in this case, which it doesn’t.
IMHO: the problem EIO is trying to solve is not even technically hard, people just want “fibers”, a cond, some io blocking at the fiber level, and synchronous buffered/unbuffered channels with select.
What is genuinely hard is providing something where there isn’t a ton of ego, that is just the right amount of bland that people are willing to digest it, and that it doesn’t piss them off too much.