I’m working on a stateful and websocket server on Node. We require a piece of read-only data that is important for the biz logic and save it in Node’s global scope, and recently we have to invalidate this require cache and re-require to allow changes of this piece of data at runtime. My question is should we worry simply reassigning the global variable the result of the re-require would cause issues between concurrent connections which read this single copy of data at different phases? Thanks!
-
It's unclear what "read this single copy of data at different phases" means. I think we'd have to see the code for reassigning the data and then have you describe more specifically what you're concerned about. node.js runs your Javascript single-threaded so there's no opportunity for other code to run in the middle of a variable assignment (like there might be in a multi-threaded system). – jfriend00 Nov 03 '18 at 05:43
-
What about the worker threads? – user917099 Nov 03 '18 at 05:46
-
If a line of code reads this global variable and assigns its value to another local variable before the reassignment to the global var, would the value of this local variable be automatically refreshed after the reassignment? – user917099 Nov 03 '18 at 05:51
-
What worker threads? If you're talking about webWorkers in the browser (which are not in node.js), then they don't have access to shared variables with the main thread. They can only communicate data with the main thread by sharing a copy of data via message passing. There are no Javascript worker threads in node.js. – jfriend00 Nov 03 '18 at 06:12
-
I meant the worker thread supported by the module of “worker_threads” – user917099 Nov 05 '18 at 20:22
-
The experimental worker_threads support in node.js v11 does not directly share variables between threads. So, there are no global variables that are shared between worker_threads or between a worker_thread and the main node.js environment. Instead, they communicate with each other using messages and can pass data between them using messaging (much like webWorkers in the browser). So, since they don't directly share variables, there can't be an atomic assignment issues between them. – jfriend00 Nov 06 '18 at 00:54
1 Answers
Is global variable assignment atomic on NodeJS?
Because node.js runs your Javascript as single threaded only, all assignments are atomic in Javascript.
Should we worry simply reassigning the global variable the result of the re-require would cause issues between concurrent connections which read this single copy of data at different phases?
You don't have to worry about an assignment not being atomic.
If a line of code reads this global variable and assigns its value to another local variable before the reassignment to the global var, would the value of this local variable be automatically refreshed after the reassignment?
Whether the module that previously had access to the data will see the new data after assignment or not depends upon the precise details of the code and what's in the variables. To comment specifically on your situation, you'd have to show us the actual code and what is in the variables that are assigned in the operation.
Here's a general description of assignment in Javascript. Assignment does something different based on what's in the variable.
Primitives are copied when assigned. Objects are assigned by just sharing a pointer to the object (no copying). So anyone with a pointer to the same object will see all property changes on that object since they point at the exact same object. But, if you assign a new object to the master variable, then all others will still have a pointer to the previous object not the new object.
Here are a few examples to illustrate:
let master = {name: "John"};
// x gets pointer to the same object that master points to
// both master and x point to the same object
let x = master;
console.log(x.name); // "John"
// update property on master
// but, both variables point to the same object so both see
// the change in the property value on that object
master.name = "Alice";
console.log(master.name); // "Alice"
console.log(x.name); // "Alice"
console.log(x === master); // true, they both point to the same object
// reassign a new object to master variable
master = {name: "Drew"};
// x still points at original object that was originally in master
// and knows nothing about the whole new object in master now
console.log(master.name); // "Drew"
console.log(x.name); // still "Alice", not "Drew"
console.log(x === master); // false, not the same object
Primitive data types such as numbers or booleans are assigned by copy so after assigning the contents of one variable to another, there is no connection at all between the two variables. They each have their own content of the data so changing the value of one variable has no effect on the content of the other variable.
// primitive data value
let master = 2;
let x = master;
console.log(x); // 2
master = 10;
console.log(x); // still 2

- 683,504
- 96
- 985
- 979
-
-
Thanks! I’m just reading your answer. The codebase is huge and for commercial use, so probably I will understand the answers and apply them to the code instead of sharing it. – user917099 Nov 05 '18 at 20:25