Do we need to be able to work with non-blocking sockets without std.Io in Zig?

I have asked the same question multiple times already:

It looks like the answer in Zig 0.16 is “no”.

That’s okay — maybe I’m the only developer who needs this functionality.

But if you also need non-blocking sockets without std.Io, this is the place to speak…

This is why I posted in the brainstorming category.

2 Likes

I need it as well for my project, it seems from your usecase in your last cited post that std.Io.Evented on a single thread would suite your taste (if I understood the docs correctly).

I’m currently waiting for networking to be implemented on std.Io.Uring before making the switch from having to handroll my own.

2 Likes

I’m maybe projecting here, but the leading tone of the title question for this thread isn’t my favorite.

Given that Zig can link against libc functions very easily and make syscalls on Linux directly, if you need to work with non-blocking sockets without std.Io in Zig, you very much can. If code for that was removed from the standard library or was made otherwise inaccessible in the 0.16 release cycle, that removed code is MIT-licensed, so you should be able to reuse it in your own projects.

So, if the question was the non-leading “Are we able to…?” the answer is “yes”.

If the question is the non-leading “Should std have prominent ways to circumvent participating in std.Io?” I think the answer really is “no”: the std.Io work becomes more powerful the more you can really thread it through all of your codebase. The library should really commit to it, “main is a goroutine”-style. If even std and the Zig compiler cannot do without workarounds, for me that would signal a design issue.

4 Likes

It was a huge amount of work to provide wrappers for system calls that are OS‑independent.
Why was this work removed? Any “io” still has to call into the OS anyway…

Interesting fact: some months ago Odin devs added nbio

non‑blocking I/O and event loop abstraction layer over several platform‑specific asynchronous I/O APIs

But you are not forced to use it - net still exists.

Yes, the title was my way of kindly saying that the direction of std and Io design is a regression.

It is not a problem for 0.16, 0.17 — just try‑and‑error…

But if it will not change, it will be a bad decision.

1 Like

Big point of Io interface is to avoid the whole blocking / non-blocking IO split, as well as async runtime ecosystem split (rust). Having all zig code go through a Io interface makes the code also more reusable and testable.

I can foresee a future where ziglibc also does all Io through a given std.Io instance, making even C libraries you use go through the zig Io.

If you don’t care about these aspects, then yeah you could start by copying the old 0.15.2 code and maintaining your own portable OS abstraction layer. That will have issues and caveats when mixed with std.Io that you and any consumer of the project would have to be aware of.

3 Likes

I’m not talking about IO intent here—I mean throwing the baby out with the bathwater.

1 Like

Not really sure what you are saying. std is not stable, seeing std changes breaking user code is nothing new. I just tried to give you some idea as to why the std.posix (which had its own problems, in addition to being completely unusable on freestanding) probably does not exist anymore, as it could drive people to use the wrong abstraction which std designers want you to avoid.

1 Like

How would you want to work with non-blocking sockets?

A) You either have to use platform APIs, poll/epoll/iouring/kqueue/iocp and they are all different, the wrappers do not provide much help here.

B) Or you use even loop abstraction, which stdlib didn’t provide in the past, you either used libxev, or libuv. You can use zio this way, even on 0.16.

C) Or you fully embrace the go-style blocking model and commit to Io.

I did it on 0.15.2 but in 0.16 std.posix does not exist

1 Like

The way I’m reading this thread I feel like the actual blocker here is that std.Io.Evented is incomplete and does not yet implement working with sockets, but at the same time the old std.posix abstraction was already removed, so you have no good abstracted way to use non-blocking sockets in 0.16. Correct?

If so, I think the best course of action for your particular project would be to stay on 0.15.2 for the time being, skip 0.16, and wait for a future version where the std.Io.Evented socket implementation is done.

5 Likes

so my reply to What’s everybody working on? will be

I am waiting :joy:

1 Like

To complete my point, and perhaps answer the question in the thread title:

Do we need to be able to work with non-blocking sockets without std.Io in Zig?

I believe (from what I understand about the future plans - disclaimer: that might be incorrect) the answer actually is no. What we do need is to wait for std.Io to catch up to this use case, if we want to use an abstraction for it.

Well, either that. Or you can just carry on with 0.15.2 for now and tell everyone about that :slight_smile:

I haven’t upgraded my own projects either yet. It’s not a requirement to stay on the bleeding edge all the time, not even to post on that thread (which I did). There are projects still being built with 0.14, and that is completely fine as well.

2 Likes

waiting for Zig; meanwhile i am going to port this 0.15.2 project to Odin, where non-blocking sockets are still supported :grinning_face:

1 Like

it is not kind to be passive aggressive.

5 Likes

I don’t think you’d be able to do without std.Io because AFAIK, core library/APIs have it embedded, so it becomes the way to go. Except if there’s a way you can provide your custom interface, which still forces you to std.Io-style of async or concurrency.

One of the reasons I hesitated for making my tool (Tina) in it, because I couldn’t see a way. But at least they’d solve async/concurrency better than many languages.

1 Like

Mea culpa