Live data from Hacker News

Local async executors and why they should be the default

maciej.codes

261–270 of 327 posts

Re: Local async executors and why they should be the default

#261

Earlier quoted context omitted.

They are superficially functionally identical, but OTP (which is what I think you meant when you wrote OTC) goes a lot further than just some syntactic sugar. It is effectively a part of a distributed operating system that focuses on reliability at the cost of some other factors. It does that one thing and it does it extremely well with a footprint that can span multiple pieces of hardware. No operating system comes…

IDK how I typo'd OTC lol, sorry about that. What you're talking about is the fact that Erlang as a VM is well built. That is irrelevant to whether or not supervisory trees are equivalent to what an OS provides. > No operating system comes close to delivering that kind of reliability. Erlang runs on an OS though. Like, Erlang would inherently always be limited by the reliability of the underlying system and in fact re…

Yes, but those processes are much lighter weight than OS processes and can be created and destroyed in a very small fraction of the time that the OS does the same thing.

> Like, Erlang would inherently always be limited by the reliability of the underlying system and in fact relies entirely on it for preemption.

This is factually incorrect, sorry. The Erlang VM uses something called 'reductions' which preempt Erlang processes when their computational slice has been reached which has absolutely nothing to do with the OS preemption mechanism.

And an Erlang system can span multiple machines with ease, even if those machines are located in different physical locations.

Erlang processes are more along the lines of greenthreads than full OS processes but they do not use the 'threads' mechanism the OS provides for the basic scheduling. The VM does use OS threads but this is mostly to decouple IO from the rest of the processing.

Oh, and BEAM/Erlang can run on bare metal if it has to.

Re: Local async executors and why they should be the default

#262
post #155

Earlier quoted context omitted.

I used "async" long before Node too. It's one of the reasons I knew to stay away from Node. "ad-hoc implementation of async" I think you're confusing the problem with the solution. I solve this sort of thing in Go all the time. This is literally what I was doing yesterday. It's fine in that context. You had to reach for async because it was the only option in your context, not because it was the best choice. Async as…

Go is internally doing async-like cooperative multitasking. You just don't see it because they actually integrated it into the language well.

Which is the proper way of doing it. As soon as you expose all that plumbing a whole generation of inexperienced programmers are going to use it to build their sandcastles with and then you can spend the next two decades on the cleanup. Such stuff should be implemented once and made bulletproof rather than to give everybody a box with interesting shiny parts that will explode when used wrong.

Re: Local async executors and why they should be the default

#263

Earlier quoted context omitted.

You realize people have been doing those things since the 70s?

Yes. The state of the art technology has not percolated everywhere. Google's tech stays locked up in Google. Parallelism in many languages that are mainstream is difficult to get right and error prone. I don't think most developers should be working with low level threads or synchronization primitives for business purposes. I am working on a notation and runtime and I'm thinking of automatic parallelisation. There is…

Google is not the 70s, and they haven't really done much, and not recently.

Google's big thing in that area maybe was MapReduce, which was quite behind the state of the art when they first introduced it.

I believe they eventually moved to BSP, which is more in line with what academia have been developing since the early 90s, but that's not really proprietary stuff.

But in any case, if you're just talking about scheduling graphs of tasks, there are thousands of competing libraries that do it.

https://en.wikipedia.org/wiki/Algorithmic_skeleton

Just go to the frameworks and libraries section.

Re: Local async executors and why they should be the default

#264

Earlier quoted context omitted.

Maybe HN should auto-pull title from URL, and then add the posters title as a form of "subtitle/comment"

This assumes those titles are usable, which they often are not.

Populating the field automatically might nudge people toward doing the right thing, though.

Re: Local async executors and why they should be the default

#265
post #258

Earlier quoted context omitted.

Rust didn't choose async because it was popular. You can go ahead and read the massive, multi-year discussions on the topic if you'd like. They've been going on since before 1.0.

I read them at the time. The gist was basically "it has been empirically established that async is the right way to do concurrency" - ie, it was because of Node.

That's nonsense

Re: Local async executors and why they should be the default

#266

Earlier quoted context omitted.

IDK how I typo'd OTC lol, sorry about that. What you're talking about is the fact that Erlang as a VM is well built. That is irrelevant to whether or not supervisory trees are equivalent to what an OS provides. > No operating system comes close to delivering that kind of reliability. Erlang runs on an OS though. Like, Erlang would inherently always be limited by the reliability of the underlying system and in fact re…

Yes, but those processes are much lighter weight than OS processes and can be created and destroyed in a very small fraction of the time that the OS does the same thing. > Like, Erlang would inherently always be limited by the reliability of the underlying system and in fact relies entirely on it for preemption. This is factually incorrect, sorry. The Erlang VM uses something called 'reductions' which preempt Erlang…

> Yes, but those processes are much lighter weight than OS processes and can be created and destroyed in a very small fraction of the time that the OS does the same thing.

Yes, that is true. I don't think that is relevant to the semantics of the constructs.

> The Erlang VM uses something called 'reductions' which preempt Erlang processes when their computational slice has been reached which has absolutely nothing to do with the OS preemption mechanism.

That preemption relies on the runtime yielding at every function call. The only thing that can actually preempt a process mid instruction is the kernel, and actually it can't do that either it's the hardware that yields to the kernel.

> And an Erlang system can span multiple machines with ease, even if those machines are located in different physical locations.

Yes, that's not unique to Erlang, obviously one can launch processes on arbitrary machines.

> Erlang processes are more along the lines of greenthreads than full OS processes but they do not use the 'threads' mechanism the OS provides for the basic scheduling.

I think you're getting hung up on implementation details. The abstraction is semantically equivalent. One might be faster, one might be heavier, one might have some nice APIs, but in terms of supervisory primitives, as I said before, the only thing required is `link` and processes have that.

I'm too lazy to go to the various paper Joe cites but if you take the time you'll find that many of them are about processes

Re: Local async executors and why they should be the default

#267
post #82

Earlier quoted context omitted.

> Also, IMO it's relatively easy to use Send-bounded future in non-Send(i.o.w. single-threaded) runtime environment, but it's almost impossible to do opposite. Ecosystem users can freely use single threaded async runtime, but ecosystem providers should not. We have Send and non-Send primitives in Rust for a reason. You could use Arc/Mutex/AtomicUsize/... everywhere on a single thread, but you should use Rc/RefCell/Ce…

There is quite some support for the second option. But it is not advertised at all . E.g. there is an entire local task pool impl in tokio_util, but it is not enabled by default and at least for me was difficult to find. https://docs.rs/tokio-util/latest/tokio_util/task/struct.Loc... I wrote an entire local executor pool before finding that thing and ripping my code out again... At the very least the support for task…

And yet glommio exists separately from tokio, because apparently it couldn't be achieved using tokio.

https://www.datadoghq.com/blog/engineering/introducing-glomm...

I am eager to see what comes of tokio-uring, though. Especially if someone comes up with a good API for reads using shared buffer pools... that one might cause API changes everywhere.

Re: Local async executors and why they should be the default

#268
post #47
post #44

Earlier quoted context omitted.

Having written a lot of async and sync rust, and having both components interact with one another, calling async stuff from a sync context isn't even that ugly these days. But maybe it's stockholm syndrome.

It's OK but not great. Ideally library authors should provide a sync facade so people don't have to deal with this, like reqwest does.

Where it really breaks down is that there's no spawn without tying the library to e.g. tokio.

Also, the other way around might be simpler. If the library wants to be async, make it async-only, and let callers block_on it. https://docs.rs/tokio/latest/tokio/runtime/struct.Runtime.ht...

Re: Local async executors and why they should be the default

#269

I'm still not sure what async (cooperative multitasking) gives over green threads (preemptive userspace multitasking)

Lower overhead. It's the same reason you would need to avoid a GC. It may not be for everyone, but that isn't a rust goal necessarily.

It's not that simple.

The article is specifically complaining about how the design of Rust's async ecosystem forces one to use wasteful Arc> etc in places where the data has no reason to move across threads.

Meanwhile, a greenthread system can happily use local state without atomics.

I personally want Tokio and Glommio to have a baby that inherits good parts of both parents.

Re: Local async executors and why they should be the default

#270
post #15

While the article mostly focuses on the cognitive cost, which I deeply sympathize with, I do wonder about the runtime performance cost. Are there any good benchmarks actually quantifying the impact of all that extra thread-safety and the hoops that it adds? I'm not asking simply due personal interest in seeing the numbers, but also because if we want to steer the community towards this non-threadsafe direction it wou…

You might be interested in these. tl;dr People are literally reimplementing tokio (differently) just to avoid this cost.

https://www.youtube.com/watch?v=PbgTyCSDPrs

https://itnext.io/modern-storage-is-plenty-fast-it-is-the-ap... https://news.ycombinator.com/item?id=25220892

https://github.com/DataDog/glommio https://www.datadoghq.com/blog/engineering/introducing-glomm...

Post reply on HN