Skip to content

Comment on Comparing Haskell and Node concurrency performanceparent

Comments

Having done programming with both threaded and event-looped systems, I think that event loops (when done well) cause less cognitive overhead. With threaded systems, I was constantly worrying about how things need to be locked and what happens if two things run simultaneously. Event-looped systems make the break points explicit, so I know precisely when other things might run.

"Callback hell" is IMO a terrible way of doing event-loop systems, as the nesting can get confusing. For implicit event loops like Node, I strongly prefer the Promises approach (preferably with async/await sugar); for explicit event loops (I only have practical experience with Arduino, though I've also a passing acquaintance with the classic 69k Mac as well) I like to build a set of event-driven state machines with cooperative multitasking. If properly designed, these keep everything nicely separated so you can follow the logic without any trouble, while also avoiding the concurrency concerns of a threaded system.

I don't actually see how promises help. In particular, it seems to encourage people to build systems that basically horde promises in odd places.

I greatly prefer first class models for where things queue up, and then to use producer/consumer objects against those queues.

I'm not sure what you mean by "horde promises in odd places"--you use a promise whenever something is happening asynchronously, certainly, but I'm not sure what's odd about that. Maybe this is an antipattern I haven't encountered yet?

I think producer/consumer and promises cover two different use cases (with some overlap). Indeed, when I have a work queue it frequently involves promises: queueing a work item returns a promise which will resolve when the work is complete, and part of executing a work item is returning a promise so the consumer knows when the task is done and can start in on another one.

I have seen paths that will generate upwards of 10 promises and then put them together at the end. In theory, this shouldn't be a problem and the code was readable enough. Reasoning about all of the different ways backpressure can happen was not as easy.

Compared to knowing that you have a set of queues that ultimately feed into other queues. It is much clearer to reason about the throughput of individual queues and take that into consideration when designing new queues in the system.

It is basically like someone throwing a ton of outlets on a wire going through a room. I mean, yes. You can do that. Often won't even cause issues. However, for large enough systems, you ultimately need to know what the load on that circuit will be and it is not acceptable to put yet another plug extender there.

I switched to babel pretty early on precisely to be able to use async/await... I wrote several wrappers around other systems to make them work cleanly in that model. It's been exceedingly nice.

I've been using babel to great effect on client-side apps which have to be transpiled/bundled anyway, but I've been avoiding it on the server side in an attempt to avoid the mental overhead of another item in the build toolchain. So far it hasn't been enough of an issue to warrant adding another tool, but I'm eagerly awaiting native async/await in NodeJS (scheduled for version 8 AFAIK).

Yeah... I usually develop with babel-node (babel-cli), then do the transpile as part of the publish for integration/production... Which works out well enough imho. It's also not too hard to script[1] if you're doing that. The script itself is a work in progress, and will probably change it to stage-3 since I think everything I am interested in is at that stage at this point.

[1] https://github.com/tracker1/react-redux-materialui-boilerpla...

I started using it a while ago now (around the time of the iojs split), as I was writing a lot of scripts to migrate/clone data between two systems. It saved a lot of what would have been more complicated code in the end...

It is available now in 7 behind a command line flag.

Yes, but this comment[1] makes me nervous:

However, Node v7 is based on V8 54, whose async/await implementation has some bugs in it (including a nasty memory leak). I would not recommend using --harmony-async-await in production until upgrading to V8 55; the easiest way to achieve that would be to wait for Node 8.

Also, I'd rather not use a non-LTS version in production since I don't want to have to keep track of changes. Most of the stuff I maintain sits untouched for months between releases; I think there might even be a few things still running on 0.10.

[1]: https://github.com/nodejs/promises/issues/4#issuecomment-254...

Thanks for the info! I'm still using babel on the server side for my side projects where I use async/await.

AboutSource Built by g1lg1l

Hackerly is an independent reader for Hacker News, built on the public HN API. Not affiliated with Y Combinator.