News for hackers. Stuff that matters.
Re:We 30x'd our Node parallelism by 7777fps on Friday December 13, 2019 @10:24AM (#21782349)
> We were running 4,000 Node containers (or "workers") for our bank integration service. The service was originally designed such that each worker would process only a single request at a time. This design lessened the impact of integrations that accidentally blocked the event loop, and allowed us to ignore the variability in resource usage across different integrations. But since our total capacity was capped at 4,000 concurrent requests, the system did not gracefully scale.

I can't be the only person who reads stories like this and wonders how they arrived at that solution in the first place?

Failing to scale because their previous approach to scaling was a worker per request, a model which was roundly moved away from, because that's how CGI and Apache modules worked and it didn't scale well.

I thought one of the key selling points with Node was an fully async standard library, enabling better scaling in process.

But then you read stories like this, and I find it hard to relate to the original problem.

Re:We 30x'd our Node parallelism by bjacokes on Friday December 13, 2019 @10:53AM (#21782621)
There are a couple of reasons that the legacy scaling model was viable for us. As mentioned in the post, only 1/10 of our traffic was from the API, which gave us a roundabout way to scale by diverting resources. And it's only viable to use this model of scaling when the business value of a request is high – we were originally quite happy to spin up more containers when we reached our scaling limit. That's the pragmatic reason why we were processing one request per container.

In terms of what issues caused us to move away from parallelism in the first place, it was all the CPU-bound stuff that you might expect: ReDoS-style issues, post-processing arrays in very large edge cases, programmer error, etc.

Re:We 30x'd our Node parallelism by abalone on Friday December 13, 2019 @11:13AM (#21782829)
> In terms of what issues caused us to move away from parallelism in the first place, it was all the CPU-bound stuff that you might expect: ReDoS-style issues, post-processing arrays in very large edge cases, programmer error, etc.

But these are not parallelism problems. These are single threading problems, which the core problem with Node.js, not parallelism in general. Hence I think the question stands: why did you choose node for this?

Re:We 30x'd our Node parallelism by bjacokes on Friday December 13, 2019 @12:16PM (#21783415)
It was chosen about 6 years ago when the product was first being developed, so most of us on the engineering team weren't around when the decision was made. The main choice we're making at this point is: what's the impact and ROI of a language migration vs getting Node to work as well as we can?
Re:We 30x'd our Node parallelism by ubu7737 on Friday December 13, 2019 @12:47PM (#21783670)
> what's the impact and ROI of a language migration vs getting Node to work as well as we can?

Hire an architect costs what? Putting the genie back in the bottle was a problem Plaid baked into its early success, which is common with startups hiring engineers with zero architecture knowledge.

Re:We 30x'd our Node parallelism by crazygringo on Friday December 13, 2019 @11:58AM (#21783243)
Yeah, I don't get it either, at all. The original poster wrote below:

> In terms of what issues caused us to move away from parallelism in the first place, it was all the CPU-bound stuff that you might expect: ReDoS-style issues, post-processing arrays in very large edge cases, programmer error, etc.

But it's trivial (a single line) in Node to place breaks in CPU processing to allow the event loop to fire, and as for "programmer error"... many commenters below are also complaining async programming is too hard or finicky.

But that's like complaining about C because pointers are hard, or Java because OOP is hard, or databases because planning indexes is hard.

Once you "get" async, pointers, OOP, or indexes, it's easy. And it's part of your job as a professional programmer to get it. Async is no trickier than anything else.

The setup in the first place makes absolutely no sense to me, using a language exactly opposite of how it's meant to be.

Re:We 30x'd our Node parallelism by bjacokes on Friday December 13, 2019 @05:11PM (#21786078)
In one case I cited elsewhere in the comments, an engineer had called ramda.uniq on an array of nested objects which was occasionally very large. When calling into external packages, I don't think we have as much control over yielding to the event loop, but I could be wrong. I know that there are some JSON/regex libraries that give you some protection on this front.

I agree that it would be nice if all developers were infallible – I'm reminded of a friend describing their company, where "we don't write tests because we all write good code". At a certain point, you have to look for processes – linters, monitoring, testing, language choices [1] – where people can't shoot themselves in the foot. (Code reviews being only moderately less fallible than a single engineer.) It's not enough to just say "be better" whenever bad code is written.

I think when the decision was made (years ago) to handle a single request per container, they couldn't find such a process to prevent event loop blockages, other than migrating an already-large codebase away from Node. As others have pointed out, maybe such a migration is necessary – after all, event loop blockages are still an inherent risk because of how Node works. It's just a lower risk than it was a year or two ago, because we've significantly improved our usage of the event loop, and also have tooling in place to catch blockages before they become an issue.

[1] https://news.ycombinator.com/item?id=18564643

Re:We 30x'd our Node parallelism by crazygringo on Friday December 13, 2019 @06:46PM (#21786705)
Oh, interesting about external libraries.

Yeah, external libraries for Node ought to be designed so that any function that ever might take any length of time whatsoever should always be callable as async. But if they're badly designed or not intended for large inputs, they might not be. You'd definitely need to find another library or write your own there, so I get that.

Re:We 30x'd our Node parallelism by markandrewj on Friday December 13, 2019 @12:16PM (#21783411)
The issue is that many developers that are coming from synchronous programming don't get asynchronous programming. They could both improve the code by not writing blocking code, and also using something like the cluster module (https://nodejs.org/api/cluster.html).
Re:We 30x'd our Node parallelism by crazygringo on Friday December 13, 2019 @12:56PM (#21783738)
I get that.

What I don't get is how nobody treats it as an issue when developers coming from Python or Java to C don't get pointers.

The assumption is that you learn.

But for some reason, people think it's "OK" to not get async, that it's the language's fault rather than the programmer's. That's what I don't understand. It's like a different cultural standard gets applied.

Re:We 30x'd our Node parallelism by markandrewj on Friday December 13, 2019 @01:08PM (#21783860)
I agree with you, but I think many developers get reluctant to change when they have been doing something one way for a long time, especially if they feel that one way works fine. I can also understand the position, as sometimes it can be fatiguing when technologies are constantly changing. For this project though, if they are actively going to avoid asynchronous programming, they may have been better off choosing a synchronous language.
Re:We 30x'd our Node parallelism by ubu7737 on Friday December 13, 2019 @03:21PM (#21785050)
There is simply no excuse for this. You are a software engineer or you are not, the cadence of change is part of the technology aspiration.

I have no patience for persons who don't belong to the discipline.

Re:We 30x'd our Node parallelism by sergiotapia on Friday December 13, 2019 @11:09AM (#21782790)
At some point you have to take a step back and realize you've grown beyond your tech and reach out for something else. Elixir sounds like a great fit for these problems.

For example Discord reached out to Rust and built tiny Rust components that are called from Elixir for their server user list. Some servers have 200,000+ people online, and Elixir wasn't cutting it performance wise. Rust, boom now it works.

Re:We 30x'd our Node parallelism by eshyong on Friday December 13, 2019 @10:39AM (#21782479)
I feel like this article is missing a crucial piece of information: why was integration code was blocking the event loop in the first place?...
Re:We 30x'd our Node parallelism by rynop on Friday December 13, 2019 @10:27AM (#21782372)
Agreed. This is the second scratch my head moment from the Plaid engineering team blog recently.
Re:We 30x'd our Node parallelism by tluyben2 on Friday December 13, 2019 @12:24PM (#21783476)
> I can't be the only person who reads stories like this and wonders how they arrived at that solution in the first place?

No you are not. I wonder which CTO would allow this; like everyone here, the exact case is not really clear (or at least why this solution is a great solution for it), but this sounds like a weird solution (and expensive) to some issue. I really don't understand these 'solutions' and I am almost 100% sure I (with a team! but the point that this is not the best solution for the problem) can whip up something far simpler and more efficient for this problem. But ofcourse there are problems that might fit?

Re:We 30x'd our Node parallelism by ilaksh on Friday December 13, 2019 @10:55AM (#21782644)
They didn't actually understand Node very well at first and then later they figured it out.
Re:We 30x'd our Node parallelism by liveoneggs on Friday December 13, 2019 @10:53AM (#21782620)
Pretty sure apache + cgi would scale better :)
Re:We 30x'd our Node parallelism by praseodym on Friday December 13, 2019 @11:32AM (#21783014)
Related, from the article:

> We hypothesized that increasing the Node maximum heap size from the default 1.7GB may help. To solve this problem, we started running Node with the max heap size set to 6GB [..], which was an arbitrary higher value that still fit within our EC2 instances.

Sounds like they were utilizing their EC2 instances very poorly. Why not run more workers per instance, or switch to an instance type with less RAM (or more CPUs)?

Re:We 30x'd our Node parallelism by tracker1 on Friday December 13, 2019 @04:14PM (#21785562)
They were using ECS, it also looks like they had to work through a couple bottlenecks to get multiple requests per node working well... I think they could get further by using the newer workers api, since gRPC doesn't work with the cluster module.
Re:We 30x'd our Node parallelism by api on Friday December 13, 2019 @10:50AM (#21782580)
I wonder what percentage of the massive compute power of huge cloud data centers is spent just chugging away on ugly clunky hacks to run bad code?
Re:We 30x'd our Node parallelism by asdfman123 on Friday December 13, 2019 @11:18AM (#21782891)
Quite a large percentage. I worked on a site that got 1 request per second and they were able to handle it by spinning up like 20 VMs. Turns out they were just using Entity Framework wrong. Whoops.

But also, though, you have to consider that most places aren't Plaid, and most places developer time is more expensive than throwing an extra machine at the problem.

Re:We 30x'd our Node parallelism by Crystalin on Friday December 13, 2019 @10:30AM (#21782402)
I got the same feeling. We use node and usually split to 500 concurrent requests per process.

Still interesting...

Re:We 30x'd our Node parallelism by Vesuvium on Friday December 13, 2019 @10:49AM (#21782571)
The way it happens always: many people working to a solution, not agreeing on one and then comprising on something in the middle, even if it makes no sense.
Re:We 30x'd our Node parallelism by phoe-krk on Friday December 13, 2019 @10:28AM (#21782378)
> I thought one of the key selling points with Node was an fully async standard library, enabling better scaling in process.

We still have an event loop that is trivially blocked by very simple programmer errors, destroying the whole advantage that you describe here.

The fact that Node ships a fully asynchronous standard library doesn't in any way fix the fact that Node is a runtime for a language that itself is a mistake.

Re:We 30x'd our Node parallelism by nicoburns on Friday December 13, 2019 @10:31AM (#21782409)
> We still have an event loop that is trivially blocked by very simple programmer errors, destroying the whole advantage that you describe here.

So they fixed the issue that some requests blocked... by making all requests blocking.

Re:We 30x'd our Node parallelism by phoe-krk on Friday December 13, 2019 @10:50AM (#21782582)
This is the worst kind of software engineering.

There is a massive deadlocking design mistake in the centre of the language - literally a huge red button with DO NOT PRESS printed on it. Thousands of programmers pass it by every single day, or hour, or minute, and the creators of the runtime insist that it is impossible to fix that button whatsoever; instead, all users need to work around it by ensuring that their code in no way presses that red button on purpose or even by accident.

These people insist that it is impossible to program normally and in a language that is actually sane and does not advertise obvious and gaping design mistakes as "features of the language". These people advertise the analogue of Python's Global Interpreter Lock as the core foundation of their language.

These people advertise Node and the language it implements as practical for implementing multithreaded applications. Posts such as this show what sort of bullshit it is; it is only practical to use Node for parallelism if each single Node instance is only ever run single-threaded. You don't parallelize by running multiple threads, you parallelize by running multiple Node runtimes.

This is no longer an act against productivity or usability. This is simply insane and shows one of the most basic things that are wrong about Node's language and approach. It is impossible to write a multithreaded program if your language of choice makes it trivial, and practically unavoidable, to globally lock your whole runtime with every single line of code you write and import as your dependencies.

Re:We 30x'd our Node parallelism by winrid on Friday December 13, 2019 @11:15AM (#21782847)
Running a Node worker for each thread is standard practice.

No different than having a dedicated threadpool for asynchronous programming on the JVM.

Yes blocking the event loop is easy. No it's not THAT easy. I've never done it because you think about it while writing code. It's part of the environment. I have had to fix lots of reports etc that try to load up the world and iterate through it in a loop that doesn't yield to the event loop. It's possible to never make that mistake by understanding your environment (just like how managing pointers in C is "hard").

Re:We 30x'd our Node parallelism by Osiris on Friday December 13, 2019 @11:30AM (#21782995)
> Yes blocking the event loop is easy. No it's not THAT easy. I've never done it because you think about it while writing code.

To be pedantic, all JavaScript functions block the event loop. It's just that the vast majority of functions execute so quickly that the amount of time your function blocks is very short.

I once had a loop that processed tons of data and would block the event loop for 1-3 seconds. I ended up solving it by writing an asynchronous loop which used promises and process.nextTick() to make each iteration a separate execution block on the event loop. But I've only had to do something weird like that once in 10 years of node development.

Re:We 30x'd our Node parallelism by winrid on Friday December 13, 2019 @09:50PM (#21787469)
Right sorry. I meant for a significant amount of time that took down production or caused serious issues. I've taken down prod in other ways though :p

At one company I built API middleware that calculated time spent in the event loop vs waiting on dependencies (other apis, Redis, etc) by managing a couple counters per request. It was very helpful.

Re:We 30x'd our Node parallelism by eshyong on Friday December 13, 2019 @11:06AM (#21782757)
I mean, running multiple node runtimes (aka multiprocessing) actually sounds like a reasonable compromise for parallelism. That's the standard solution for dynamic languages without great multithreading support. If you needed great multithreading support then Node probably wasn't the right choice for you in the first place, but for most applications, it's probably fine.

However, running multiple containers for parallelism sounds a little bit crazy. In the worst case, each container may be running on its own server, but even assuming multiple containers per host, I'm guessing they were running an insignificant number of instances, which is probably why they were able to save $300k in server costs.

Re:We 30x'd our Node parallelism by phoe-krk on Friday December 13, 2019 @11:12AM (#21782816)
Yet this is the case mentioned in the article.

> We were running 4,000 Node containers (or "workers") for our bank integration service.

Re:We 30x'd our Node parallelism by eshyong on Friday December 13, 2019 @11:23AM (#21782932)
Yes, I agree. I'm arguing against your characterization of node as a poor runtime. For many line-of-business applications node is a fine choice. However, plaid has to integrate with many banks which only expose web pages, not APIs, so I'm guessing that they have to do a non-trivial amount of CPU work to scrape and process HTML responses. For this, it may not be such a good choice.

All I'm saying is that the choice of language is (usually) not the issue. Poor architecture design causes a lot more problems than whether you choose python/java/ruby/node for your webapp.

Re:We 30x'd our Node parallelism by neillyons on Saturday December 14, 2019 @04:15AM (#21788591)
Yeah I’m confused why they didn’t start with running multiple processors per container. There must be a reason?
Re:We 30x'd our Node parallelism by MayeulC on Friday December 13, 2019 @11:23AM (#21782927)
> [javascript] makes it trivial, and practically unavoidable, to globally lock your whole runtime with every single line of code you write and import as your dependencies.

As someone not well-versed in js, could you describe one such case? Concurrent access to a global from two threads? Mutexes? My background is more with systems languages and I have done very little js for the browser, so I do not see that big red button.

Re:We 30x'd our Node parallelism by phoe-krk on Friday December 13, 2019 @11:28AM (#21782971)
An event loop is basically a single thread that executes functions from a FIFO queue. A function can put itself on a queue by "yielding", which means, allowing other functions to execute.

If your function blocks, for example, by performing a wait on something without yielding, then nothing else gets computed because of the wait, but the event queue is occupied since the function has not yielded. This breaks the cooperative part of the cooperative multithreading mechanism of Node.

Re:We 30x'd our Node parallelism by MayeulC on Friday December 13, 2019 @11:38AM (#21783063)
All right, thank you. So it's basically the same as any other non-preemptive multitasking design.

If the event loop is part of the Node language/runtime, I can see the case for making it preemptive.

Re:We 30x'd our Node parallelism by Izkata on Saturday December 14, 2019 @12:09AM (#21787941)
> So it's basically the same as any other non-preemptive multitasking design.

All this has happened before. All this will happen again.

Re:We 30x'd our Node parallelism by neillyons on Friday December 13, 2019 @11:39AM (#21783073)
In Python, you can execute time.sleep(10_000) in an asyncio program, which means it wont yield back control to the event loop effecting preventing the runtime from doing anything for 10 seconds.

In Javascript world I guess you could do the same by replacing time.sleep with some CPU bound code. eg a big calculation or an infinite for loop.

Re:We 30x'd our Node parallelism by tracker1 on Friday December 13, 2019 @04:20PM (#21785617)
Yes... often JSON serialization and deserialization are the biggest blockers, if they're using puppeteer (as suggested in other comments) that can have its' own instance overhead. I think with ECS they used the "easy" button to start off with and now that they've hit those limits have had to refactor, which isn't unreasonable imho.

I'm working on a project now that's very CPU bound and using limited workers behind an MQ as a distributed RPC behind a fronting API interface so that I can handle scaling... though it's also a Windows-only library involved. There's definitely an art to scaling certain types of workloads and many different options. Sometimes the simplest solution you can come up with really is the best option.

Re:We 30x'd our Node parallelism by jononor on Friday December 13, 2019 @11:00AM (#21782692)
The blog in question indicates some uncommon and questionable engineering practices with Node.js. There are likely hundreds of success stories for every one like that.

The first Node.js service I wrote and maintained, processed thousands of requests in parallel and was successfully in production until the company it was developed for ran out of money.

Re:We 30x'd our Node parallelism by x86_64Ubuntu on Friday December 13, 2019 @11:44AM (#21783109)
But how many of these "questionable" practices get held up as engineering marvels by the creators of the monstrosity? When you look at this blog post, you can see the author really felt a sense of pride in this Frankenstein and wanted to show the whole village.
Re:We 30x'd our Node parallelism by tracker1 on Friday December 13, 2019 @04:22PM (#21785640)
I didn't get that impression.. what I got was a few probably common issues that will come up when trying to handle more parallel requests with Node. Note: gRPC doesn't support cluster, so you'd have to manage your own multi-thread (Workers) or multi-process (fork) options.
Re:We 30x'd our Node parallelism by JoeAltmaier on Friday December 13, 2019 @11:04AM (#21782735)
Multithreading is still possible - for clarity of code. Multiple processing threads are running in parallel, but only one at a time. This is a subset of useful applications, but not totally worthless.
Re:We 30x'd our Node parallelism by phoe-krk on Friday December 13, 2019 @11:13AM (#21782832)
Yes, it is possible, and actually works - unless one of your threads blocks the event loop and prevents all others from running. This way it takes a single locking thread to halt the whole system, whereas with standard threads a single stalling thread does not cause all others to starve. This is a risk in Node that multiple other runtimes of other languages do not have.
Re:We 30x'd our Node parallelism by james-mcelwain on Friday December 13, 2019 @11:13AM (#21782827)
Are you seriously arguing against event loops as a category? Blocking in non-blocking code is going to be an issue whether the language is C or JavaScript (duh).
Re:We 30x'd our Node parallelism by phoe-krk on Friday December 13, 2019 @11:15AM (#21782846)
For these kinds of programming, yes, I argue against it. A single stalling function in Node deadlocks the whole system; a single stalling thread in the C++ model still permits other threads to run. This is a risk that is completely avoidable by not using languages which require event loops at their core.
Re:We 30x'd our Node parallelism by megous on Friday December 13, 2019 @12:45PM (#21783655)
JavaScript doesn't require event loop design. You can do a PHP like backend design with JS, where each request is handled by a fresh process, and all JS functions block. There's nothing in the language that prevents this.

Some features would become unusable, like Promises and async/await, but those would be worthless in such a design anyway.

Re:We 30x'd our Node parallelism by phoe-krk on Friday December 13, 2019 @04:18PM (#21785592)
Nobody does it. Nobody implemented it yet. Nobody made it production ready. That is what a few minutes of googling gave me.

As much as I'd like to see it, your JS without an event loop is a purely theoretical construct so far.

Re:We 30x'd our Node parallelism by megous on Saturday December 14, 2019 @08:18AM (#21789367)
I did blocking design using Duktape for my runtime Linux distro reinstallation tool and some other projects. It works fine and it's easier than implementing async aware bindings.

I wouldn't implement it for the HTTP server/backend use case, because I find the blocking/share nothing architecture of PHP limiting.

The point is the language doesn't prevent this kind of architecture.

Re:We 30x'd our Node parallelism by Vesuvium on Friday December 13, 2019 @10:51AM (#21782600)
It's simple but effective.
Re:We 30x'd our Node parallelism by duxup on Friday December 13, 2019 @10:38AM (#21782472)
>by very simple programmer errors

I can't help but also feel that is also an issue and in another given language this issue might not happen ... but they'd hit another.

It's so easy to say "don't do X because problem Y won't happen" but hard to predict what happens when you move from (language, platform, or whatever) X to (language, platform, or whatever) Z.... and I suspect people often hit issues and realize that maybe Y wasn't the problem.

I see it all the time and I feel like "Wait guies I'm not sure we're fixing the right thing!?!?!"

This article raises a lot more questions than answers IMO.

Re:We 30x'd our Node parallelism by earthboundkid on Friday December 13, 2019 @10:53AM (#21782622)
Async is just modern cooperative multitasking, and just like the 90s, it's easy to accidentally lock the whole system.
Re:We 30x'd our Node parallelism by wiredfool on Friday December 13, 2019 @11:03AM (#21782722)
Yeah, I remember just how nice it was going from Cooperative MT to Preemptive multi tasking -- the general view was that anything that only did Cooperative MT was just a Toy.

I'd bet that the orders of magnitude of speed from Moore's law did in CMT by making PMT doable without a huge speed hit.

Nothing I've seen from async is cleaner, easier to maintain, or better from a cognitive load POV. It's just more efficient for certain types of loads because you're being a consenting adult and not breaking things.

Re:We 30x'd our Node parallelism by lmeyerov on Friday December 13, 2019 @11:57AM (#21783240)
CMT for concurrency + DLP for parallelism is a he'll of a lot more scalable in LOC than the unsafe hammer of preemptive. We keep unsafe parallelism to only tiny tiny tiny GPU code snippets.

Node's concurrency and parallelism probs don't require deep lang changes but runtime ones and some ergonomics to be closer to Go -- and not far IMO bc of last few years of work for Async, safe (fresh env) eval, and json/buffer msg's.

More exciting would be something like Apache Arrow / Berkeley's 'Plasma', but that stuff is still more exploratory.

Re:We 30x'd our Node parallelism by brendanw on Friday December 13, 2019 @02:08PM (#21784387)
For folks looking for a good primer on the terminology and history of cooperative vs preemptive multi tasking, I took a pause on reading this thread to look for an article

https://dev.to/nestedsoftware/is-cooperative-concurrency-her...

This article does a good overview

Re:We 30x'd our Node parallelism by neillyons on Friday December 13, 2019 @11:17AM (#21782872)
What language were you using that had preemptive multi tasking?
Re:We 30x'd our Node parallelism by phoe-krk on Friday December 13, 2019 @11:02AM (#21782715)
We are no longer in the 90s. The code has increased in volume a hundredfold and it comes from literally everywhere. You can no longer trust everything on your machine or your network to be bug-free or otherwise non-hostile.

Creating a system in the 21st century that tries to follow ideals from the 90s gives us the kind of idiotism that we can witness here.

Re:We 30x'd our Node parallelism by jerf on Friday December 13, 2019 @11:12AM (#21782825)
I think you may have misinterpreted earthboundkid; the claim isn't that it worked in the 90s, the claim is that it was already broken in the 90s.

You are otherwise on the right track, though Node does technically have one advantage, which is that it is a cooperatively-scheduled island in a preemptively-scheluded overall OS. In the 1990s, when the cooperatively-scheduled program was not cooperative, you locked the machine, not the process [1]. There is a reason why Apple went very aggressive with the OSX rewrite; the previous Systems had basically written themselves into a corner where they had to use cooperative multitasking because so much code made use of the implicit promises it provides, yet they could no longer afford to compete with Microsoft if they didn't get off it it, because the complexity just kept going up, up, up and the problem was going to continue getting exponentially worse.

For a Node program, you only have to account for the Node program itself, not everything running on the computer. Still, you're in the same exponentially-growing-complexity trap (with a very initially-safe-seeming low exponent, but it still gets you in the end), you just reset yourself back to a point earlier on the curve.

[1] There are various details, caveats, interrupts, etc, the picture is more complicated than one sentence can convey, but the principle still held and it was still possible to wedge the machine fairly badly for varying periods of time with simple bad code.

Re:We 30x'd our Node parallelism by reaperducer on Friday December 13, 2019 @11:34AM (#21783023)
If I thought my bank was running thousands of node containers in parallel to handle transactions, I think I'd look for a new bank.
Re:We 30x'd our Node parallelism by winrid on Friday December 13, 2019 @11:21AM (#21782913)
I mean, if you write slow code in a high throughput environment you'll just kill the CPU from context switching between threads instead.

It doesn't matter if it's in an event loop or thread per request. Architect things correctly.

Re:We 30x'd our Node parallelism by davedx on Friday December 13, 2019 @10:51AM (#21782591)
> trivially blocked by very simple programmer errors

Can you give an example please?

I think it's much easier to block a thread with C#'s async programming model than node's...

Re:We 30x'd our Node parallelism by dmitriid on Friday December 13, 2019 @11:00AM (#21782686)
Node only has one thread. Everything else follows.
Re:We 30x'd our Node parallelism by coddle-hark on Friday December 13, 2019 @11:09AM (#21782792)
No it doesn’t. We’ve had good models for concurrency in single-threaded systems for a while now.
Re:We 30x'd our Node parallelism by dmitriid on Friday December 13, 2019 @05:19PM (#21786132)
You say no it doesn't and then speak about concurrency models for single-threaded systems. Choose one :)

Node can't not be single-threaded. Because Javascript is. Node.js is single threaded. It has a single event loop in a single thread, and all the "concurrency" is simply queued on that loop. It offloads some tasks to libuv for some system-related tasks but that's it. And the thread pool that libuv creates is very limited.

Anything that doesn't end up in libuv (that is, probably vast majority of user code) will only ever run in one thread... because Javascript is single-threaded hence V8 is single-threaded hence Node.js you get the gist.

And of course, node.js even has a separate documentation section titled "Don't Block the Event Loop (or the Worker Pool)" [1] because it's trivial to block the event loop.

[1] https://nodejs.org/en/docs/guides/dont-block-the-event-loop/

Re:We 30x'd our Node parallelism by willglynn on Saturday December 14, 2019 @12:37AM (#21788017)
Not OP, but… concurrency is not the same as parallelism. This is an important hair to split:

https://stackoverflow.com/a/24684037/1026671

"Concurrency" doesn't warrant scare quotes even when describing a single threaded program.

It's true that Node.js allows one task to block many others, but that's an implementation detail of Node.js, not a guaranteed result which necessarily applies to any program using only one OS thread. Other programs suffer from analogous starvation/deadlock/livelock/priority inversion problems, but those would be implementation details too, not guaranteed results from using multiple OS threads.

Re:We 30x'd our Node parallelism by dmitriid on Saturday December 14, 2019 @10:40AM (#21790005)
I never said anything about other programs. I never said that other single-threaded programs don't suffer from the same problems. That's is sort of the point. Node.js is single-threaded and, as a result, had all the same problems a single-threaded programs has. And no amount of hand-waving can change that fact.
Re:We 30x'd our Node parallelism by coddle-hark on Saturday December 14, 2019 @06:57AM (#21789077)
You’re focusing on single-threadedness like that’s a problem but it’s not. For example, you can run multiple processes on a single core system just fine — even if one of those processes hangs.

AFAIK there’s nothing in the JS language that forces a single-threaded implementation. I think the real reasons that Node is single threaded are a) legacy and more importantly b) a lot of existing code would break if events were dispatched in parallel.

Re:We 30x'd our Node parallelism by dmitriid on Saturday December 14, 2019 @10:37AM (#21789989)
> you can run multiple processes on a single core system just fine — even if one of those processes hangs.

Yes, I can. Node.js doesn't do that.

Re:We 30x'd our Node parallelism by PixyMisa on Friday December 13, 2019 @12:38PM (#21783589)
The model being "don't do that".
Re:We 30x'd our Node parallelism by davedx on Saturday December 14, 2019 @08:13AM (#21789346)
Nodejs has an event loop running in a single thread, but most calls you'll do will be async (and therefore let other operations continue to be executed by the event loop). The entire programming ecosystem is async by default.

The only thing I can think of where a programmer could "easily" block the event loop would be if they explicitly use sync filesystem or other blocking calls instead of the async API. But in any project with reasonable code review I don't think this would happen.

Re:We 30x'd our Node parallelism by dmitriid on Saturday December 14, 2019 @09:01AM (#21789515)
> The only thing I can think of where a programmer could "easily" block the event loop would be

Parsing JSON. Or executing a regex. Or anything, really, that blocks the thread: https://nodejs.org/en/docs/guides/dont-block-the-event-loop/

There's no magic

Re:We 30x'd our Node parallelism by davedx on Sunday December 15, 2019 @10:33AM (#21796682)
Well it's a question of magnitude. In theory everything blocks the loop even if it's only 1 CPU cycle before it yields.

In practice I've rarely seen production nodejs applications cause significant CPU blocking issues. Huge JSON parses sometimes, yes, but then it has to be one hell of a payload to cause any significant issue.

Regexes? Have you really seen regexes block CPU for significant time relative to the rest of the application? I'm sure it's possible with a crazy enough runaway pattern, but I've never seen it happen.

I really don't understand what people are getting at here. Nodejs is an async programming model, it's non-blocking by default. Are the people saying it's trivial to break nodejs developers?

Re:We 30x'd our Node parallelism by dmitriid on Monday December 16, 2019 @10:28AM (#21803695)
My original response was to this [1]

> I think it's much easier to block a thread with C#'s async programming model than node's...

Which spawned a discussion in which people seemingly think that you can't block a thread in node, or that since node is async it means it's not single-threaded etc.

Since it is single-threaded, it's quite possible that the original post wouldn't need 4000 node instances otherwise (emphasis mine):

> We were running 4,000 Node containers (or "workers") for our bank integration service. The service was originally designed such that each worker would process only a single request at a time. This design lessened the impact of integrations that accidentally blocked the event loop

[1] https://news.ycombinator.com/item?id=21782591

Re:We 30x'd our Node parallelism by techterrier on Friday December 13, 2019 @10:42AM (#21782498)
I wonder if all this was at root, pickup up jobs from a message queue and they only wanted each process to only have one job in flight at once.
Re:We 30x'd our Node parallelism by asdfman123 on Friday December 13, 2019 @11:16AM (#21782860)
> I can't be the only person who reads stories like this and wonders how they arrived at that solution in the first place?

Here's how it probably worked: they liked Node, they liked containers, they put Node into containers and it worked, and they stuck with it as the user base grew.