Live data from Hacker News

How One Missing `var` Ruined our Launch

blog.meloncard.com

131–140 of 223 posts

Re: How One Missing `var` Ruined our Launch

#131

Earlier quoted context omitted.

Node is single-threaded, so yes they are shared. Requests are basically just multiplexed inside the same message loop. In my opinion it wouldn't be quite as scary if js didn't make it so damn simple to accidentally define a global variable (like in this instance, where it was never actually declared in globally-scoped code).

Why does threading matter? You can have multiple JS global objects all running on the same thread. See any web browser.

JS in browsers is not multi-threaded. There's only one JS thread where requests from async calls are queued: http://ejohn.org/blog/how-javascript-timers-work/

When dealing with true multi-threading you have all sorts of issues you need to worry about, like locking for writing, worrying about deadlocks, etc. that make coding much more difficult.

Re: How One Missing `var` Ruined our Launch

#132
Oh wow. I've faced this exact same problem with missing `var`s more than once before. It's pretty ridiculous that JavaScript makes variables global by default.

Sorry to hear about your tragedy, hope it doesn't cause too many issues in the long run.

Re: How One Missing `var` Ruined our Launch

#133
post #61

Earlier quoted context omitted.

Well, that's what global variable means, shared among all functions in the process. Since there's only one process to handle all requests, they can access the global variables. All languages used in web server that don't spawn a new process for each request have the same feature.

In JS, "global variable" means "property of the global object". No reference to "process". It's trivial to have a single-process JS application with multiple JS global objects in it. Case in point: any web browser (and renderer processes don't change this: every iframe on a page has a separate global object). It's just that Node _chose_ to reuse the same global object for multiple requests instead of using a clean ex…

(I assume) the reason that node chose to go with a single global object (which is optional[0]) is that JS gets a bit hinky when dealing with multiple contexts: e.g., an array returned from a function defined in a different context will not satisfy `[] instanceof Array`, since the receiving module's instance of `Array` is not strictly equal to to called module's copy of `Array`.

In practice, this problem is why you see `Array.isArray`, `jQuery.isArray`, `_.isArray` and friends so often -- they exist to give a canonical, non-"check if any member of X's inheritance chain matches Y.prototype" way to determine if a given instance is actually an array.

So, in summation: yes, it's weird that Node has this, but ultimately it's a lesser-vilified problem of JavaScript's.

[0]: https://github.com/joyent/node/blob/master/lib/module.js#L51 -- `NODE_MODULE_CONTEXTS=1 node ` will run separate modules in separate global contexts.

Re: How One Missing `var` Ruined our Launch

#134

Earlier quoted context omitted.

Node is single-threaded, so yes they are shared. Requests are basically just multiplexed inside the same message loop. In my opinion it wouldn't be quite as scary if js didn't make it so damn simple to accidentally define a global variable (like in this instance, where it was never actually declared in globally-scoped code).

Why does threading matter? You can have multiple JS global objects all running on the same thread. See any web browser.

Indeed you can - but I suspect I know why Node has avoided this.

If you did take advantage of the runtime's support for multiple global objects, what would those global objects correspond to? The most natural scope would be "user session" - but if you go that route, now you support stateful user sessions. And before you know it you have developers storing loads of user session state in the server's RAM and wondering why they keep running out - and lose the ability to easily fail over to another server process.

So I imagine Node's author decided it was better to just keep things simple and discourage use of globals.

Re: How One Missing `var` Ruined our Launch

#135

Earlier quoted context omitted.

Python doesn't let you write outside of local scope without a special keyword. Exactly the inverse of JS. If you want to write to global state, and you're aware that you're writing to global state, then you use the "global" keyword. That's all.

It still conjures up variables out of thin air. sum = 0 for v in someList: smu += v print sum # prints 0, doh!

Actually no:

  >>> for v in (1,2,3):
  ...   smu+=v
  ... 
  Traceback (most recent call last):
    File "", line 2, in 
  NameError: name 'smu' is not defined

Re: How One Missing `var` Ruined our Launch

#137

Earlier quoted context omitted.

Python doesn't let you write outside of local scope without a special keyword. Exactly the inverse of JS. If you want to write to global state, and you're aware that you're writing to global state, then you use the "global" keyword. That's all.

It still conjures up variables out of thin air. sum = 0 for v in someList: smu += v print sum # prints 0, doh!

[deleted]

Re: How One Missing `var` Ruined our Launch

#138

> I would posit here that nothing I could do in best practice (manual front-end testing, unit testing, error handling, etc.) would have caught the offending line. Sorry, that's incorrect. If you cannot fully simulate your environment for purposes of validation, you're not covering your bases.

Are you saying that the definition of an adequate test setup is one that will necessarily catch any possible race conditions? That sounds like a necessary idea if you're building real-time embedded systems for aircraft operation or something, but for a lot of applications, developing a test harness to that standard would take considerably more time and effort than building out the actual product.

The problem wasn't a race condition, it was an improperly scoped variable. If a different variable name had been used, the failure would have been easy to identify. Testing for the result of something improper wouldn't be appropriate here, either.

But, if the environment is such that it is easy to manifest this condition, I would argue that such a test setup should definitely be considered, given the potential for failure.

Post reply on HN