各リクエストを独自のドメインにラップする Express/Connect ミドルウェアを作成するにはどうすればよいですか?
5 に答える
スピーカーデッキのこのスライドセットは、簡潔な概要を示しています。
スライドからミドルウェアコードを表現します。
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();
});
更新:以下で説明するアプローチは、Connect または Express アプリケーションで使用できるconnect-domain NodeJS モジュールに実装されています。
Express 3 の時点で、express.createServer
は非推奨であり、そのコールバックはミドルウェアに変換する必要があります。ミドルウェアでは、リクエスト オブジェクトと結果オブジェクトをリクエスト ドメインに追加して、それらによって発生したエラーがドメイン エラー ハンドラによって処理されるようにすることが重要です。
私のミドルウェアは次のようになります。
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);
});
http.createServer
最上位ドメイン内から呼び出す場合は、リクエスト ドメインにリクエストとレスポンスを追加することを避けることができますが、ドメイン ドキュメントは、リクエストごとのドメインがベスト プラクティスであることを示しているようです。
上記のコードは、要求ドメインを強制的に破棄するなど、ドメインのクリーンアップ アクションを実行しないことに注意してください。私のミドルウェアは、代わりにミドルウェア スタックを介してエラーを再度渡し、後で特定のエラー処理ミドルウェアによって処理されることを選択します。YMMV。
ストック交換して良かった
var app = express.createServer();
と:
var domainCreate = require('domain').create;
var app = express.createServer(function (req, res, next) {
var domain = domainCreate();
domain.run(next);
});
次に、ミドルウェアで、プロパティを process.domain に追加するか、追加のエラー処理を追加できます。
これは遅い回答ですが、express-domain-moddlewareモジュールを確認してください。リクエストごとに新しいドメインが自動的に作成されます。アクティブなドメインは、ルートの process.domain で参照できます。次に例を示します。
//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.");
}));
}));
}));
});
ドメインは現在、次のノードで非推奨です。
https://nodejs.org/api/domain.html
「ゾーニング エラー」の目的で、非同期コードを適切な方法で記述できるライブラリを作成しました: https://github.com/vacuumlabs/yacol。その利点の 1 つは、非常に優れたセマンティクスでドメインのような動作を行えることです。見てみな!