在expressjs中设置请求清理中间件
我正在尝试编写一个使用postgresql作为后端的expressjs服务器。 每个请求都是通过调用pg.connect
来获得池连接( client
)以及在连接不再需要( done
)后将其返回到池的方法。 例如:
function dbConnect(req, res, next) { if (res.locals.pgCtx) { next(); return; } pg.connect(dbConn, function (err, client, done) { if (err) { res.send(500, err.message); } else { app.locals.pgCtx = res.locals.pgCtx = { client: client, done: done }; next(); } }); } app.use(allowCrossDomain); app.use(express.methodOverride()); app.use(express.compress()); app.use(express.bodyParser()); app.use(express.logger()); app.use(passport.initialize()); app.use(express["static"](webRootDir)); app.use(dbConnect); // <-------------- app.use(authenticate); app.use(app.router); app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); app.set('view engine', 'jade'); app.set('views', webRootDir); app.engine("jade", jade.__express); indexHandlers = [fetchConstData, function (req, res) { res.render(templatesDir + 'index', { constData: app.locals.constData, env: app.get('env'), user: req.user, admin: isAdmin(req.user.role), host: req.host }); }]; app.get('/', indexHandlers); app.get('/index', indexHandlers); app.get('/index.html', indexHandlers);
我的问题是,尽pipe我可以将dbConnect
作为全局中间件插入到任何其他中间件之前运行,但是为了将连接返回到池中,还需要能够在所有中间件运行之后进行清理。
理想情况下,无论请求如何结束,都应该有一种方法来指定全局中间件在所有请求特定的运行之后运行。
-
res.send(...)
- 抛出exception
- 将err对象传递给
next()
请注意,任何请求特定的中间件都可以以这种方式终止链。
现在我只能看到这种方法:
- 通过注册一个自定义的全局error handling程序中间件而不是
express.errorHandler
来挂钩负面结果。 - 用一个定制版本replace
res
对象中的res.send
方法,该定制版本将连接返回到池,然后继续执行原始的res.send
实现。
所有这一切都有一个强大的黑客气味。 我想这样做是正确的,所以我问是否有一种方法来注册的东西像请求清理中间件?
编辑
必须将静态内容处理程序移到dbConnect
中间件上方,否则我们会泄漏数据库连接,直到没有更多连接可用,并且服务器无法提供任何服务,因为dbConnect
从不会返回等待连接释放。
有一个finish
事件,您可以在响应对象上进行侦听,并在响应结束时发出:
function dbConnect(req, res, next) { res.on('finish', function() { // perform your cleanups... }); ... }