Live data from Hacker News

After a year of using Node.js in production

geekforbrains.com

51–60 of 248 posts

Re: After a year of using Node.js in production

#51
post #47
post #25

I've been on a similar learning curve with Node over the last year, and it has certainly been a rougher incline than other languages I've used. The whole async situation needs to settle down, it's completely unacceptable to write code with callbacks, promises, etc. This is because they are not just challenging to deal with, but intrinsically wrong in concept. I have to wait for a database query to complete, then pass…

Callbacks are ugly, but are probably the semantically simplest way to handle asynchronicity. Promises are ugly too, but are semantically the same thing as async/await. I agree that promises and callbacks are not pleasing to the eye, but they are completely logical ways to do things.

So in PHP, you would go (I haven't tested these snippets, just writing them out here):

  $username = get_username();
  echo "Hi, ".$username;
  do_other_things();
In Node, using promises, you have to write:

  get_username().then(function(username) {
    return res.send("Hi "+username");
  }).then(function() {
    do_other_things();
  })
And if you're using regular callbacks, forget it: you'd have to nest do_other_things in the callback of get_username(!). It just makes things very awkward.

I understand what you mean about sync vs async calls. I won't pretend I have a better solution. I don't mean to say callbacks are illogical, just a bad way to write programs. So maybe not 'wrong in concept', I can concede that. But I think async/await can make things more readable again, i.e.:

  var username = await get_username();
  /* carry on... */

Re: After a year of using Node.js in production

#52
post #48

> You use Grunt!? Everyone uses Gulp!? Wait no, use native NPM scripts! Although couched as a criticism this is actually the community fixing itself. The evolution from Grunt > Gulp > npm scripts is movement away from needless complexity towards simplicity. Npm scripts are effectively just Bash commands that build and manage your project, which sometimes employ small, unixy tools written in Node. This self correction…

NPM scripts are just a different problem. See: https://twitter.com/sindresorhus/status/724259780676575232?l... https://github.com/ReactiveX/rxjs/blob/a3ec89605a24a6f54e577... Already people are coming up with new "solutions" to this problem that looks more like Grunt. It's a repetitive circle. Personally I just use Make.

So somebody found a project somewhere on the internet with an exceptionally complicated build process, and you use it to say npm scripts are broken? Sorry, that's absurd. Looking at that particular build process, I don't think a Makefile could have been crafted to make it much simpler or smaller. In that example, the problem lies with the complexity of what they're having to do, not the tool.

Npm scripts are really just shell scripting, which means all the real progress happens in the unixy Node tools that do the heavy lifting, where it should be. It's a future proof and scalable approach for the vast majority of projects imo.

Re: After a year of using Node.js in production

#53
post #12

Earlier quoted context omitted.

Yeah, so some js devs might need to stop overselling javascript to everyone, pretending it is the one language that people are waiting for years...Just saying.

You should try to surround yourself with developers who don't have such attitudes. I am a fan of JavaScript, I love Node.js and I will often times suggest it to newbies. But I don't pretend it's the be all/end all of languages. Just like any other language it has its strengths and weaknesses. It's up to you to decide if it's the right choice for you.

This "I love [some language]" thing seems to be quite common in JS circles. Maybe that is part of the problem. Being in love is not good foundation for making objective decisions.

Re: After a year of using Node.js in production

#54
Just FYI, the Koa framework makes node sane again.

Callback hell and error handling are no longer issues in node if you just embrace generators or async/await.

We use Koa in production and serve billions of requests just fine.

If I had to go back to Express I'd say no.

Re: After a year of using Node.js in production

#55
Now all of a sudden, having types and some standards to gather around doesn't sound like a bad idea anymore ;)

I agree with one of the commenters: Lessons already learned by older engineers (who went through similar woes with other languages/tools) are being re-learned again and again.

The software industry is in a sorry state.

Unless you are a very disciplined team with a very strong sense of writing modular code, don't use Node.js for any larger project. And even then, the single-most useful function in an IDE 'Show Call Hierarchy' will never be available when using a dynamically typed language.

That is not an issue for smaller projects. However, long before you even get close to the the million lines of code project size, your tools will fail you. Your debugging/refactoring times will explode and adding a new feature will seem unsurmountable.

Instead, let's just re-write everything from scratch because the cool hipster that wrote your backend a year ago has left for greener pastures...

I won't even try to guess the amount of technical debt produced with Node.js and the likes each day in the bay area.

And, yes, I just used Node.js to write a Slack-bot. It was fun, took me two hours and got me up and running quickly. That's the beauty of it. Just be aware of the dangers.

Re: After a year of using Node.js in production

#56
post #25

I've been on a similar learning curve with Node over the last year, and it has certainly been a rougher incline than other languages I've used. The whole async situation needs to settle down, it's completely unacceptable to write code with callbacks, promises, etc. This is because they are not just challenging to deal with, but intrinsically wrong in concept. I have to wait for a database query to complete, then pass…

I find that JS often seems to tie programmers in the most extraordinary knots just to implement even quite simple logic, because of the single-threaded nature of the language.

In the programming model used by most other mainstream languages today, if you've got some work to do that interacts with some external system and might take a while, you'd probably start another thread for that task. You'd write the required logic in the usual linear fashion, and just let the thread block if and when it needs to. Modelling this using fork/join semantics and techniques to co-ordinate access to shared resources from different threads are reasonably well understood ideas.

Because there is no general support for concurrency and parallelism in JS, you only get one thread, and so in most cases you can't afford to ever block it. Consequently, you get this highly asynchronous style that feels like writing everything manually in continuation passing style, just so you can carry on with something else instead of waiting. That in turn leads to callback hell, where you start to lose cohesion and locality in your code, even though usually you're still just trying to represent a simple, linear sequence of operations.

Async/await help to bring that cohesion and locality back by writing code in a style that is closer to the natural linear behaviour it is modelling. However, even those feel a bit like papering over the cracks in some cases. Async/await kinda sorta give us some simple fork/join semantics, but as the blog post linked from the parent shows, we have a lot of promise-based details remaining underneath.

Fundamentally, the problem seems to be that JS is increasingly being used to deal with concurrent behaviours, but it lacks an execution model and language tools to describe that behaviour in a natural, systematic way as most other widely used languages can. Being strictly single-threaded avoided all the synchronisation problems in the early days, when the most you had to worry about was a couple of different browser events firing close together and it was helpful to know the handler for one would complete before anything else started happening. I'm not sure it's still a plus point now that we're trying to use JS for much more demanding concurrent systems, though.

Re: After a year of using Node.js in production

#58

> You use Grunt!? Everyone uses Gulp!? Wait no, use native NPM scripts! Although couched as a criticism this is actually the community fixing itself. The evolution from Grunt > Gulp > npm scripts is movement away from needless complexity towards simplicity. Npm scripts are effectively just Bash commands that build and manage your project, which sometimes employ small, unixy tools written in Node. This self correction…

And someone needs to pay for the overhead of 'community fixing itself'.

And the Promise/A+ spec is so bare-bones, it is laughable. And the actual issue is that not every module is embracing it yet.

Sure, it will all be fixed. For freeeee :)

Re: After a year of using Node.js in production

#59
I think the switch to an async back-end can be more initial work than many expect. It may take some time to feel as productive, but promises become powerful and became a game changer for me over my previous work with callbacks. Error handling also becomes manageable.

What I really enjoy is jumping into new community and getting to work with tools that have built. Choosing the right ones can make or break an experience. I personally enjoyed working with Express and Bookshelf.js/Knex.

I appreciate the authors perspective, but I also don't think this should deter anyone from trying out Node. I personally have no overwhelming preference to using a Python or Javascript stack.

Re: After a year of using Node.js in production

#60
post #45

Earlier quoted context omitted.

I gave a talk about handling errors in Node a few years ago: https://github.com/pjungwir/node-errors-talk At the time the solution was "use domains", but I think domains are deprecated now. It was painful enough that I have stuck with Rails since then. I'm glad to hear that Promises are an improvement!

Domains have been deprecated since at least 0.10. As of yet there's no replacement for them and all node apps should be using them. There's no other way to catch " But ... but ... that can't happen! " type errors.

There is no replacement because they're a fundamentally broken idea. They require the following to happen, in that order:

* V8 needs to optimize try-finally

* Node core needs to add try-finally at every single place where callbacks are invoked and make sure all state and resource cleanup is properly done to support domains

* Popular libraries need to also add try-finally handlers for the above.

As to why this is a problem in node and not so much in other languages, its because with node callbacks, the call stack goes both ways. In other languages, libraries mostly call their dependencies' code. In node's CPS style, you call the library but the library also calls your closure code. The semantics for the 2nd part aren't well defined in node - the loose law basically says: I wont call you twice, I'll try not to call you synchronously, and you wont throw (and if you do the behavior is undefined).

With promises there is a contract and its enforced by the promise implementation. Since Promises actually have error semantics, you can build resource management strategies on top of them. http://promise-nuggets.github.io/articles/21-context-manager... - and consequently there is no reason to crash your server on errors.

Post reply on HN