Earlier quoted context omitted.
Any kind of mechanism like that requires a mental model that carries a ton of state because it is no longer immediately visible what the scope of execution is. Continuations and the way Erlang handles this have far less mental overhead and help keeping the model and the mental representation of that model in sync. Differences between the two is where bugs will hide. The web isn't asynchronous it's synchronous in almo…
Oh, hey again. :) And yes I work mostly with Elixir for years and Erlang's model is just irreplaceable so far. You're quite right that everything is synchronous but all the Erlang "processes" (green threads, fibers or w/e people want to call them) are preemptively and forcibly switched. And that has basically eliminated 95% of all parallel programming problems. I would kill for Erlang's concurrency / parallel primiti…
Local async executors and why they should be the default
251–260 of 327 posts
Re: Local async executors and why they should be the default
#252Earlier quoted context omitted.
> in operating systems the kernel does that for you Does it really? I am not an uber Linux expert but I have only heard of systemd doing that. Serious question, I'll appreciate more examples. > As for scale, I don't really know how to reconcile "I'm fine just paying another 20 dollars" with "I'm worried about how my kernel will schedule my processes". Sorry if I was unclear, I meant it as "I don't want to worry if th…
The kernel is ultimately the thing that preempts your process and allows it to be killed, restarted, etc. It's also what handles things like "the connection was dropped", or "the thing timed out", etc. Userland facilitates management of those actions in a user oriented way through helpers like systemd or your container orchestrator or whatever. It doesn't make much difference though, you can say it's systemd, the ker…
> Why not "I don't want to worry about if my kernel will properly schedule N clones of my single threaded program so I'll just bump my hosting so my program has the throughput I require" ?
Boring answer: I never prioritized that way of work, I admit. And after gaining tons of experience in several ecosystems and languages I got burned out and right now I can't bring myself to learn systemd properly.
> Also I didn't suggest single threading, I generally build things as 'async/await' on the inside and 'service oriented' on the outside. So when there's some new domain I don't spawn a new task, I just spawn a separate process.
Ah, I see. Fair, I would and have done the same (though that comes with some care when coding the thing so it can determine what it needs to do so spawning the 2nd copy doesn't step on the toes of the first one).
Re: Local async executors and why they should be the default
#253Earlier quoted context omitted.
Oh, hey again. :) And yes I work mostly with Elixir for years and Erlang's model is just irreplaceable so far. You're quite right that everything is synchronous but all the Erlang "processes" (green threads, fibers or w/e people want to call them) are preemptively and forcibly switched. And that has basically eliminated 95% of all parallel programming problems. I would kill for Erlang's concurrency / parallel primiti…
In a way it really gets me: we have a very good solution and yet everybody is pushing their own novel footguns with gusto. Baffling, really when you think about it. I'm trying to imagine civil engineering with entirely new ways to design bridges every 4 months, different materials that are entirely untested but this time we'll get it right and so on. That's roughly the state of the software world.
I really think we should all pull up our sleeves and e.g. make transpilers from TLA+ to every mainstream language. (Provided we first made sure TLA+'s parallel logic is exhaustive and flawless, of course.)
I too get super ticked off these days. The programmers at large are constantly running in circles and almost nobody seems to care and everyone loves to pretend that this is exactly how things should be... Argh!
Re: Local async executors and why they should be the default
#254Earlier quoted context omitted.
> Where did it come from in its current incarnation? Node. Rust's async/await is inspired by C# (which was inspired by F#, which was inspired by Haskell). > right now threaded code is straight-up a better option on almost every metric, Agreed that people are generally too eager to reach for async when they could easily get away with threads, and fortunately Rust makes threads extremely pleasant to work with. The whol…
And yet it didn't learn that it took almost 10 years for .NET community to sort out async/await support across all layers of the stack. .NET archictects have spent last year researching Go and Java Loom approaches, and have acknowledge if it had been today, most likely that would have been the approach taken instead of async/await, as many .NET devs still get it wrong. During the "ASP.NET Core and Blazor futures, Q&A…
Re: Local async executors and why they should be the default
#255Earlier quoted context omitted.
I don't think there's a meaningful difference between an Erlang actor and an operating system process other than the upfront memory allocation size. The salient different to me is the supervisory structures. In Erlang you must compose them, in operating systems the kernel does that for you, or you move the responsibility into a distributed queue, etc. As for scale, I don't really know how to reconcile "I'm fine just…
> In Erlang you must compose them, in operating systems the kernel does that for you Erlang's supervisor trees are much more powerful than anything the kernel will do for you.
Supervisors are built on `link`, and every process in erlang must always exit with an exit status. This is identical to a process handle with a process exit status.
The whole point of supervisors is that they are extremely simple - you can implement all of Erlang's OTC and supervisory semantics with, more or less, recursive functions (which are the foundation of actors), names, and links.
Re: Local async executors and why they should be the default
#256Earlier quoted context omitted.
CPU cycles are practically free but memory latency and synchronization are not. (Hardware threads gives more CPU cycles capacity). People's scalability problems are memory related, not CPU cycles. In other words, we can't scale updating a single memory location with more hardware threads. People often want to scale the updating of something so they add threads, but the contention of memory synchronization prevents th…
You realize people have been doing those things since the 70s?
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 also Go and Erlang but this is an area I am interested in enough to have an attempt myself.
Multithreading can be difficult and I recommend this blog post:
https://bholley.net/blog/2015/must-be-this-tall-to-write-mul...
(Check my comments on HN and my profile for more details)
Re: Local async executors and why they should be the default
#257Earlier quoted context omitted.
> In Erlang you must compose them, in operating systems the kernel does that for you Erlang's supervisor trees are much more powerful than anything the kernel will do for you.
Disagree. Processes and actors are nearly identical, except that the kernel has the ultimate ability to preempt everything. Supervisors are built on `link`, and every process in erlang must always exit with an exit status. This is identical to a process handle with a process exit status. The whole point of supervisors is that they are extremely simple - you can implement all of Erlang's OTC and supervisory semantics…
Joe Armstrong's view of the software world (one with which I strongly identify so forgive me the soapbox mode) is that reliability, not throughput should be our main focus and that failure should be treated as normal rather than as exceptional and that distributed systems are the only viable way to achieve the kind of reliability that we need to bring software engineering into the world. This is a completely different kettle of fish than stringing together a bunch of services using kernel or auxiliary mechanisms, both in terms of results and in terms of overhead.
Re: Local async executors and why they should be the default
#258Earlier quoted context omitted.
Rust didn't choose async because of Node. Async's massive popularity is because of Node. It existed long before then, and that's precisely part of my point . It had a bad reputation before then, and it's slowly-but-surely reacquiring it now.
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.
Re: Local async executors and why they should be the default
#259Earlier quoted context omitted.
Disagree. Processes and actors are nearly identical, except that the kernel has the ultimate ability to preempt everything. Supervisors are built on `link`, and every process in erlang must always exit with an exit status. This is identical to a process handle with a process exit status. The whole point of supervisors is that they are extremely simple - you can implement all of Erlang's OTC and supervisory semantics…
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…
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 relies entirely on it for preemption.
> (one with which I strongly identify so forgive me the soapbox mode)
For the record, I am an extreme fan of Joe's and I routinely re-read his thesis, so you are preaching to the choir in a way.
> This is a completely different kettle of fish than stringing together a bunch of services using kernel or auxiliary mechanisms, both in terms of results and in terms of overhead.
I just totally disagree and in fact you'll find that Erlang's seminal works used the term 'processes' and in fact is based on the entire model of OS processes. Off the top of my head he cites at least two papers about processes and transactions as the foundation for reliability in his thesis.
Re: Local async executors and why they should be the default
#260Earlier quoted context omitted.
Async in its current incarnation did not come from node. Eg Haskell had async/await in 1999. https://softwareengineering.stackexchange.com/questions/3774... Node wasn't released until 10 years later.
And I have code still in production written in the "Perl Object Environment", one of several async frameworks for Perl, written before Node even existed. Also before Node existed, I had written code in the Twisted framework for Python. Node did not invent async by any means and I know it in the strongest possible sense, having used it before Node existed. But those libraries, in use for over a decade, did not make ev…
It's a kludge at best and it's quite annoying to see a first class project such as Rust be distracted like this.