sambroblog. A Blog. With words. And maybe pictures.

27Jun/110

Listening for end of response with Node/Express.JS

I'm currently working with CoffeeScript, Node, Express, and Redis to deliver on a quick'n'easy contract I've been put in charge of. This is the first time I've used any of these technologies in a proper commercial deliverables type project, and I have to say, it's been an absolute delight.

An issue I ran into was I wanted to reduce the boilerplate on handling requests, so I wrote a quick route middleware in Express to create a client connection to Redis, assigning the connection to the request object for easy use . I also wanted to be clever and have this same middleware clean up after itself when the request ended. That is, I wanted the middleware to QUIT the Redis connection when the response had been sent.

Consulting the Express/Connect/Node docs yielded no clues as to how to do this, the closest hint I found was from the Node docs indicating that a http.ServerResponse is a WritableStream. I noticed WritableStreams had a "close" event that is supposed to be called when the Stream is no longer writable. I assumed that if you call .end() on a response then it should trigger this event, so my initial middleware looked like this:

setupRedisClient = (req, res, next) =>
	req.redisClient = require("redis").createClient()

	cleanup = =>
		console.log "it worked!"
		req.redisClient.quit()

	res.on "close", cleanup
	res.on "error", cleanup

	next()

I tried using this middleware in a route, and was sad to see that the event was not being triggered.

As a last resort I started digging through the Node source, and lo and behold! I found what I was looking for in lib/http.js. Turns out when you .end() your http response, it will emit a "finish" event.

Now my Redis middleware looks like so:

setupRedisClient = (req, res, next) =>
	req.redisClient = require("redis").createClient()

	cleanup = =>
		req.redisClient.quit()

	res.on "finish", cleanup
	res.on "error", cleanup

	next()

Incoming routes that need a Redis connection simply add this middleware, and hey presto! They can use req.redisClient to their hearts content. Once a response is sent back to the client, or an error occurs with the request, the Redis connection will be cleaned up automagically! Hurrah!

Comments (0) Trackbacks (0)

No comments yet.


Leave a comment

(required)

No trackbacks yet.