Live data from Hacker News

Zig's New Async I/O

kristoff.it

131–140 of 293 posts

Re: Zig's New Async I/O

#131
post #43

Earlier quoted context omitted.

Wouldn't this only work if there's only one implementation throughout the entire compliation unit? If you use 2 allocators in your app, your restricted function type has 2 possible callees for each entry, and you're back to the same problem.

> A side effect of proposal #23367, which is needed for determining upper bound stack size, is guaranteed de-virtualization when there is only one Io implementation being used (also in debug builds!). > In the less common case when a program instantiates more than one Io implementation, virtual calls done through the Io interface will not be de-virtualized, as that would imply doubling the amount of machine code gene…

I wonder how massive it actually would be. I'm guessing it really wouldn't be all that massive in practice even if it of course is easy to create massive examples using ways people typically don't write code.

Re: Zig's New Async I/O

#132
post #123

Earlier quoted context omitted.

> If anything, it does a great job at abstracting the usage from the implementation. This is something Rust fails at spectacularly. Could you expand on this? I don't get what you mean

I am not very experienced in async Rust, but it seems there are some pieces of async Rust that rely too much on tokio internals, so using an alternative runtime (like pollster) results in broken code. Searching for comments mentioning "pollster" and "tokio" on HN brings a few results, but not one I recall seeing a while ago where someone demonstrated an example of a library (using async Rust) that crashes when not us…

Yep. The old async wars in the Rust ecosystem. It's the AsyncRead and AsyncWrite traits. Tokio has its own, there was a standard brewing at the same time in the futures crate. Tokio did their own thing, people burnt out, these traits were never standardized to std.

So you cannot use most of the async crates easily outside Tokio.

Re: Zig's New Async I/O

#133

Earlier quoted context omitted.

> (And before anyone mentions it, devirtualization is a myth, sorry) In Zig it's going to be a language feature, thanks to its single unit compilation model. https://github.com/ziglang/zig/issues/23367

Wouldn't this only work if there's only one implementation throughout the entire compliation unit? If you use 2 allocators in your app, your restricted function type has 2 possible callees for each entry, and you're back to the same problem.

Having a limited number of known callees is already better than a virtual function (unrestricted function pointer). A compiler in theory could devirtualize every two-possible-callee callsite into `if (function_pointer == callee1) callee1() else callee2()` which then can be inlined at compile time or branch-predicted at runtime.

In any case, if you have two different implementations of something then you have to switch between them somewhere -- either at compile-time or link-time or load-time or run-time (or jit-time). The trick is to find an acceptable compromise of performance, (machine)code-bloat and API-simplicity.

Re: Zig's New Async I/O

#134
post #123

Earlier quoted context omitted.

> If anything, it does a great job at abstracting the usage from the implementation. This is something Rust fails at spectacularly. Could you expand on this? I don't get what you mean

I am not very experienced in async Rust, but it seems there are some pieces of async Rust that rely too much on tokio internals, so using an alternative runtime (like pollster) results in broken code. Searching for comments mentioning "pollster" and "tokio" on HN brings a few results, but not one I recall seeing a while ago where someone demonstrated an example of a library (using async Rust) that crashes when not us…

There's two details that are important to highlight. tokio is actually 2 components, it's the async scheduler, and it's the IO runtime. Pollster is only a scheduler, and does not offer any IO functionality. You can actually use tokio libraries with pollster, but you need to register the IO runtime (and spawn a thread to manage it) - this is done with Runtime::enter() and it configures the thread local interface so any uses of tokio IO know what runtime to use.

There are ideas to abstract the IO runtime interface into the async machinery (in Rust that's the Context object that schedulers pass into the Future) but so far that hasn't gotten anywhere.

Re: Zig's New Async I/O

#136
post #78

Earlier quoted context omitted.

Not necessarily, that is one of the reasons OOP exists. Have a struct representing the set of associated activities, owning the channel.

soo, a context?

Nope, because I didn't mention it was to be passed around as a compulsory parameter, rather have your logic organised across structs with methods, hide most details behind interfaces.

Re: Zig's New Async I/O

#137

As the author of a semi-famous post about how Zig has function colors [1], I decided to read up on this. I see that blocking I/O is an option: > The most basic implementation of `Io` is one that maps to blocking I/O operations. So far, so good, but blocking I/O is not async. There is a thread pool that uses blocking I/O. Still good so far, but blocking I/O is still not async. Then there's green threads: > This implem…

Their bet seems to be that they can transparently implement real async inside an IO implementation using compiler magic. But then it means if you use that IO instance with the magic then your function gets transformed into a state machine? Then this whole thing is useless for implementing cooperative scheduling async like in rust?

No, it just means the cooperative scheduler needs to provide an io implementation that works with the rest of the scheduler.

Re: Zig's New Async I/O

#139
post #3

I feel that I have to point this out once again, because the article goes so far as to state that: > With this last improvement Zig has completely defeated function coloring. I disagree with this. Let's look at the 5 rules referenced in the famous "What color is your function?" article referenced here. > 1. Every function has a color Well, you don't have async/sync/red/blue anymore, but you now have IO and non-IO fun…

You are skipping the massive point here. If you are using a library in rust, it has to be async await, tokio, send+sync and all the other crap. Or if it is sync api then it is useless for async application. This approach of passing IO removes this problem and this is THE main problem. This way you don’t have to use procedural macros or other bs to implement multi versioning for the functions in your library, which do…

I'm not skipping anything. And in fact acknowledge this exact point:

> That being said, I don't think Zig's implementation here is bad. If anything, it does a great job at abstracting the usage from the implementation. This is something Rust fails at spectacularly.

Post reply on HN