How to use Node.js 0.8.x domains with express?

这一生的挚爱 提交于 2019-12-03 04:54:22

问题


How can I create Express/Connect middleware which wrap each request in its own domain?


回答1:


This set of slides on Speaker Deck gives a succinct overview:

  • Domains in node 0.8

Express middleware code from the slides:

var createDomain = require('domain').create;

app.use(function(req, res, next) {
  var domain = createDomain();

  domain.on('error', function(err) {
    // alternative: next(err)
    res.statusCode = 500;
    res.end(err.message + '\n');

    domain.dispose();
  });

  domain.enter();
  next();
});



回答2:


UPDATE: The approach described below has been implemented in the connect-domain NodeJS module, which can be used in either Connect or Express applications.

As of Express 3, express.createServer is deprecated, and its callback should be converted to a middleware. In the middleware, it's important to add the request and result objects to the request domain so that errors fired by them are handled by the domain error handler.

My middleware looks something like this:

var domain = require('domain');

app.use(function(req, res, next) {
    var requestDomain = domain.create();
    requestDomain.add(req);
    requestDomain.add(res);
    requestDomain.on('error', next);
    requestDomain.run(next);
});

You can avoid adding the request and response to a request domain if you call http.createServer from within a top-level domain, but the Domain docs seem to indicate that per-request domains are a best practice.

Note that the code above doesn't do any domain clean up actions, such as forcibly disposing the request domain. My middleware chooses instead to pass the error through the middleware stack again to be handled by specific error-handling middleware later on. YMMV.




回答3:


I've had good luck replacing the stock

var app = express.createServer();

with:

var domainCreate = require('domain').create;
var app = express.createServer(function (req, res, next) {
    var domain = domainCreate();
    domain.run(next);
});

Then in your middleware you can add properties to process.domain or add additional error handling.




回答4:


This is a late answer, but check out the express-domain-moddleware module. It automatically creates a new domain for each request. The active domain can be referenced by process.domain in your routes. Here is an example:

//with domain-middleware
app.use(require('express-domain-middleware'));
app.use(app.router);

app.use(function errorHandler(err, req, res, next) {
  console.log('error on request %d %s %s: %j', process.domain.id, req.method, req.url, err);
  res.send(500, "Something bad happened. :(");
  if(err.domain) {
    //you should think about gracefully stopping & respawning your server
    //since an unhandled error might put your application into an unknown state
  }
});

app.get('/error', function(req, res, next) {
  db.query('SELECT happiness()', process.domain.intercept(function(rows) {
    fs.readFile('asldkfjasdf', process.domain.intercept(function(contents) {
      process.nextTick(process.domain.intercept(function() {
        throw new Error("The individual request will be passed to the express error handler, and your application will keep running.");
      }));
    }));
  }));
});



回答5:


The domains are currently deprecated in node:

https://nodejs.org/api/domain.html

For the purpose of 'zoning errors', I've created a library which allows you to write asynchronous code in a nice way: https://github.com/vacuumlabs/yacol . One of its benefits is that you can have domains-like behavior with a very nice semantics; check it out!



来源:https://stackoverflow.com/questions/11599739/how-to-use-node-js-0-8-x-domains-with-express

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!