Live data from Hacker News

Ditching Go for Node.js

github.com

21–30 of 185 posts

Re: Ditching Go for Node.js

#21
post #6

That's the funny thing modern Node is surprisingly usable and if using TS has very advanced tooling.

It's incredibly easy to throw stuff together in Node.js, it's much harder to maintain over time. TS helps with this but you still run into really hard to diagnose memory leaks (mostly in 3rd party packages written in C++, but sometime in Node core itself). The tooling for these type of issues is really poor in my experience.

Re: Ditching Go for Node.js

#22
Hi!

I'm implementing channels/coroutines in clojure[0] and js[1].

These are alpha quality right now, but I already have channels with backpressure and async go blocks. I wrote the js implementation to show that these could be ported to any language.

The main thought behind this is: CSP - S = Communicating Processes = Green Threads

[0] https://github.com/divs1210/functional-core-async [1] https://github.com/divs1210/coroutines.js

Re: Ditching Go for Node.js

#23
I feel his pain about the lack of decent WebSockets support in Rust. There's a few Websockets implementations but all of them are meant to run on a separate port from the web server. As in, they want you to run your web server on port 443 and the websocket on... Something else. Which makes zero sense (browsers will deny access to the second port because of security features related to SSL certificates).

Also, unless you go low level (lower than frameworks like Tokio) you can't easily access file descriptors to watch them (e.g. epoll) for data waiting to be read. It makes it difficult to use WebSockets for their intended purpose: Real-time stuff.

Rust needs a web framework that has built-in support for Websockets (running on the same port as the main web server) and also provides low-level access to things like epoll. Something like a very thin abstraction on top of mio (that still gives you direct access to the mio TcpListener directly).

In my attempts to get Tokio reading a raw file descriptor I just couldn't get it working. I opened a bug and was told that raw fd support wasn't really supported (not well-tested because it only works on Unix and cross-cross-platform stuff is a higher priority). Very frustrating.

I wish the Tokio devs didn't make the underlying mio TcpListener private in their structs.

Re: Ditching Go for Node.js

#24
I don't use Go but I find the reasoning fueled by a confirmation bias to pick JS.

goroutines are now 2k. If you use 2 goroutines per connection that's 4k. If you have 10k connections that's roughly 20mb only which is very reasonable.

Re: Ditching Go for Node.js

#25
post #13
post #5

Why not use mutexes and callbacks instead of channels for pubsub?

This is not considered idiomatic Go and would be a premature optimization unless you ran a profiler and determined that channels are actually your bottleneck. It sounds like this has not been done.

Not only that, but channels are internally implemented with mutexes anyway, so a naive mutexes+callbacks implementation wouldn't be any faster.

Re: Ditching Go for Node.js

#27
post #21
post #6

That's the funny thing modern Node is surprisingly usable and if using TS has very advanced tooling.

It's incredibly easy to throw stuff together in Node.js, it's much harder to maintain over time. TS helps with this but you still run into really hard to diagnose memory leaks (mostly in 3rd party packages written in C++, but sometime in Node core itself). The tooling for these type of issues is really poor in my experience.

My main concern with node is how fast everything moves. Try to maintain a project that started with es5, then migrated to es6 (but some legacy code is still es5), then added some es2017 and now is adding slowly typescript to the monster, and all of this in just 3 years!

Things become a mess in no time, tooling changes constantly, and maintaining legacy code while developing new parts with current best practices helps you build a Frankenstein in no time.

(and don't even mention about coffee, or it'll make me start ranting about the move from coffee to es6 and now TS!)

Re: Ditching Go for Node.js

#28
post #13

Earlier quoted context omitted.

This is not considered idiomatic Go and would be a premature optimization unless you ran a profiler and determined that channels are actually your bottleneck. It sounds like this has not been done.

Not only that, but channels are internally implemented with mutexes anyway, so a naive mutexes+callbacks implementation wouldn't be any faster.

Channels have a performance overhead over handling the locking yourself. Maybe look at stuff from Tyler Treat to learn more (maybe his most recent talk? https://www.youtube.com/watch?v=DJ4d_PZ6Gns) but there are some other discussions (mostly with earlier Go versions) but maybe something changed?

Re: Ditching Go for Node.js

#29
post #17

Earlier quoted context omitted.

Seems like it should be linear??

Hopefully it's linear, or it's implemented wrong.

Hopefully, but all he said was "fanout" which could be either.

He knows it's implemented wrong, that's the point of the article: that Go doesn't make it easy for him to implement it right. The only question is the degree of wrongness. :)

Re: Ditching Go for Node.js

#30

No clue about Go, but how can it take more memory then Javascript on Node? This is hard to believe.

I think it’s the event loop model reuses more per connection. He mentions nothing is stopping you from implementing an event loop model for the pub-sub in go, just there wasn’t any library support and he didn’t want to spend time building it out when it is the default model in Node.
Post reply on HN