5 ms·
> “what else am I supposed to do when I’m waiting for a result from the database”? I can’t do anything else until I have that result. I need the result to make
by andrewguenther 9y ago
> “what else am I supposed to do when I’m waiting for a result from the database”? I can’t do anything else until I have that result. I need the result to make give to a template to give to the renderer, etc.
I dunno, maybe you could serve one of your 100 other concurrent requests?
> You can do something useful in the meanwhile and get the result later
and then immediately...
> It has nothing to do with hogging or stealing resources.
It has everything to do with this. If you're blocking on something waiting for a result while you could do something useful in the meantime, that is the definition of hogging resources.
- christophilus 9y agoHis point is that blocking while waiting should not be an expensive thing. In preemptive systems like BEAM, it's not. Blocking a process is not an issue. In Node/Windows 3.1, it is a big deal, as it means starving other work.
- pas 9y agoAwait works the same way as BEAM, no? In theory their performance and behavior should be the same. BEAM and other N:M green thread systems being maybe faster if they can efficiently use multiple threads. But since they use message passing anyway (needed for isolation), they are again almost equivalent to running multiple Node/reactive request handlers. N:M is probably useful for desktop apps. But for that single thread is (should be) always enough, so same behavior.
- kabes 9y agoWell, as the article points out, await is not pre-emptive, so it doesn't have the same fairness guarantees as BEAM. But IMO this argument is mostly theoretical as most web applications deal with simple request/response kind of things and have few long running tasks. Although a non pre-emptive system might be easier to DOS as soon as you find one input that takes a long time to process.
- pas 9y agoAwait doesn't have to be as everything (im theory) is non-blocking. Yes, I see, if you have data crunching in the event loop, you have to "manage" it, by either delegating it outside of it, or chunk it up into small pieces, and yield between. But that should result in the same performance as BEAM, because you can run 1 big runtime or many small event loops on each box, and put a load balancer in front (which is needed even for BEAM, because if you have a more threads/processes than cores throughput AND latency will suffer). Agreed on the DoS thing, but nothing, sort of a proper timeout (and/or hard RT) will save you. Yes, with Node et al. you can lose a lot of requests when you inevitably kill the runtime. But it's just as easy to DoS a different runtime. (BEAM just gives up a few seconds later.)
- jerf 9y ago"In theory their performance and behavior should be the same." This isn't about performance, it's about how you write code. In Erlang/Elixir (and also Go and Haskell), you aren't sitting there constantly explaining to the runtime over and over again how to plumb together bits of "async" code. Essentially, all code is simply presumed async, and the plumbing is always already there for you; the act of calling a function includes, for free, all the "async" plumbing. I expect anyone who has been doing this for a couple of months should have noticed it's the same plumbing, over and over again. Here's the long-running IO task. Here's what to do with it when it's done. Here's what to do with errors. Here's the next long-running IO task. Here's what to do with it when it's done. Here's what to do with errors, which is pretty similar to the last thing. Here's the next long-running IO task. Here's what to do with it when it's done. Here's what to do with errors; whoops, forget that one, which is gonna cost me during debugging but nothing in the code, runtime, or syntax affordances particularly cares that I forgot. Here's the next long-running IO task.... Yes, they do come out roughly the same in speed for Erlang/Elixir and JS, and Go can quite easily be substantially faster... and easier to write. And if we want to discuss performance, Go still isn't as fast as it could be. There's a solid reason why N:M threading can't be the fastest way to run code in general, but I don't see much reason why it couldn't be something more like 20% away from C speed in general, with some pathological cases where it's much slower and out of the question (very fast packet handling with those fancy software TCP cards, for instance).
- WorldMaker 9y agoasync/await as mentioned by the previous poster is "do-notation" for the asynchronous monad Promise<T> in modern ES/JS(/TS). It's not terribly different from the languages you mentioned, even if it is a different approach because the language started synchronous first. You don't have to do that much plumbing as with the bad old JS world of Node callbacks, just sprinkle the async/await as appropriate, make sure things stay in Promise<T> and write things do-notation style just about like you would write the equivalent synchronous code. From what I've done async/await in ES (and C#) is easier to write than Go's equivalent, but we're hitting your mileage may vary territory.
- rdtsc 9y ago> maybe you could serve one of your 100 other concurrent requests? That's exactly the problem with node.js and other promise/callback/deferred/futures mechanism - it mixes concerns. You business algorithm probably doesn't look like "1) authenticate & authorize 2) return a callback then go to select loop to process 100 other connections 3) add book to cart etc". It probably doesn't have 2) in there, and it shouldn't. The point was that that particular request doesn't and shouldn't have anything else to do besides wait for the connection from database to return a result. Sure there maybe there are 2 million other (https://blog.whatsapp.com/196/1-million-is-so-2011 https://blog.whatsapp.com/196/1-million-is-so-2011) connected clients wanting to buy a book, but the logic for a single doesn't have to care about it. That's the beauty of it. > If you're blocking on something waiting for a result while you could do something useful in the meantime, that is the definition of hogging resources. That's not something you should be doing that high up the abstraction levels. If you have to worry about it that high up there is something broken with the framework / language / library. Like the OP says, it is basically the equivalent of Windows 3.1. Nobody sane today would put their crown jewel, latest production systems running on Windows 3.1 but yet we do with when it comes to our choice of frameworks and libraries.