Reputation: 754
My use case requires node.js domains to share information across server files at a request level.
Sample Implementation in express.js
domain = require('domain');
app.use(function(req, res, next) {
var reqDomain = domain.create();
reqDomain.add(req);
reqDomain.add(res);
reqDomain.run(next);
});
More explanation at Nodejs Domains Explicit Binding
In controller / service - process.domain will provide you above created domain And you can easily bind values to this domain. For eg:
process.domain.obj = {};
This explanation is sufficient to understand the usage of Domains.
Questions
Is it safe to use domains for multiple requests ?
How to ensure process.domain is different for different requests and not the same ?
I would also like to know how such issues are handled in continuation local storage
Upvotes: 6
Views: 839
Reputation: 276306
First of all - domains are deprecated and will be removed in an upcoming release of NodeJS. I would not write new code using them.
Second of all - it's important to understand domains are not magic. They're really a simple concept. Basically, they:
Here's how one can implement domains, let's only implement it for setTimeout
for simplicity.
const oldTimeout = setTimeout;
setTimeout = function(fn, ms) { // also ...args, but let's ignore that
var trackedDomain = domain;
oldTimeout(function() {
var oldDomain = domain; // preserve old context
domain = trackedDomain; // restore context to "global" variable
fn(); // call the function itself
domain = oldDomain; // restore old context
}, ms); // that's it!
};
Something like express
can just do domain = new RequestContext
at the start and then all methods called in the request would work since they're all wrapped like in the example above (since again, it's baked into node itself).
They're being removed because of the implementation complexity they add and the fact they're leaky and error recovery has edge cases where it doesn't work.
You have alternatives, for example bluebird promises have .bind
which brings promise chains context which is a less leaky way to do this.
That said, I would just avoid implicit global context altogether. It makes refactoring hard, it makes dependencies implicit and it makes code harder to reason about. I'd just pass relevant context around to objects when I create them (dependency injection, in a nutshell) rather than set a global variable.
Upvotes: 5