3 ms·
This article is misleading. Here's the real problem: https://github.com/AndrewRademacher/fpco-article-examples/blob/master/concurrency-and-node/node-async/src/s
by jondubois 10y ago
This article is misleading. Here's the real problem: https://github.com/AndrewRademacher/fpco-article-examples/blob/master/concurrency-and-node/node-async/src/starvation-main.js#L22L32 https://github.com/AndrewRademacher/fpco-article-examples/bl...
Anyone who understands JavaScript can see that the recursion invoked in the slow route is not asynchronous (each recursive invocation keeps piling onto the call stack without ever releasing it)! You'd have to use process.nextTick (or setTimeout) if you wanted to recurse asynchronously without spawning a new process...
For these kinds of unusual, heavy computations, though, you'd be better off using the child_process module to spawn a new process and do the recursion inside that process so that it doesn't block the main event loop.
This has nothing to do with starvation. Node.js just has a completely different approach to this kind of problem.
- wyager 10y ago> Maybe Haskell does some sort of automatic multi-threading behind the scenes - If so, I'm not sure that's a good thing GHC (the leading Haskell compiler) provides an extremely advanced green threading system with the runtime. http://haskell.cs.yale.edu/wp-content/uploads/2013/08/hask035-voellmy.pdf http://haskell.cs.yale.edu/wp-content/uploads/2013/08/hask03... > I like the way it's done in Node.js - Explicitly. If you wanted to do it this way in Haskell, there are a number of monads that make it way more convenient than doing it in Node. Cont in particular can be used for cooperative concurrency. No one really uses these outside of niche cases, however, because threads are almost always a better abstraction.
- jondubois 10y agoMaybe, Golang also has similar advanced multi-threading constructs. But I do a lot of REST API (and WebSocket) work and all of the workload that happens inside my Node.js program is extremely lightweight. If I need to perform some heavy computation, I will offload it to a separate child process - Node.js forces me to put that code in a separate file/module but I actually like this because it encourages separation of concerns. It feels very natural so I don't really need any other special constructs. I looked into goroutines a while ago; it looks cool, but I probably wouldn't use them much because I don't like the idea of having code from the same source file splitting off into multiple processes/threads; it makes is harder to read and reason about the code (this is a bit like what happens with multi-threaded code when you have mutexes all over the place). To me, this feature has the same utility value as the ability to define multiple classes per source file - Ok, that's cool, but is it a good idea to do that?
- wyager 10y agoI don't really have strong feelings about source file organization, but the way it works in Haskell is that all IO actions have type "IO a", where "a" is the type of the action's result. To do multithreading, you just do e.g. foo :: IO () -- optional type declaration foo = forever (print "hi") forkIO foo Now Foo will run in its own green thread forever. Very simple. This works with any IO action. You can put it in whatever file you like. For communicating across threads you have many great options like STM. If you like Go-style chans, there are libraries that provide various types of chans.