views:

98

answers:

2

I'm writing an MVC application which serves transformed versions of user-uploaded images (rotated, cropped, and watermarked.) Once the transformations are specified, they're not likely to change, so I'd like to aggressively cache the generated output, and serve it as efficiently as possible.

The transformation options are stored in the database and used by the image servers to create the images on demand; only the original uploads are stored permanently. Caching the generated images in a local directory allows IIS 7 to pick them up without touching the ASP.NET process, i.e. by matching the route. Static images in images/ take precedence over the dynamic MVC route /images/{id}.jpg.

My concern at this point is when the user actually changes the transformation options -- the images need to be re-generated, but I'd like to avoid manually deleting them. I'm storing a last-modified field in the database, so I could append that timestamp to the URL, e.g. http://images.example.com/images/153453543.jpg?m=123542345453. This would work if the caching was handled by the ASP.NET process, which could vary the output cache by the parameter m, but seeing as I need to serve large quantities of images I'd rather avoid that.

Is there an intelligent way to get the IIS to discard static files if some condition is met?

+2  A: 

If you don't want your ASP.NET code to be invoke every time someone requests an image then I would recommend that you delete the images when updating the transformations. It is a relatively "free" operation since it just a cache and they will be regenerated when needed.

You might be concerned about tracking if the transformation is actually changed when the user updates image properties but how often will the user make changes at all. Does it matter if you need to regenerate an image a bit to often?

You could include the timestamp in the filename itself, e.g.

http://images.example.com/images/153453543_20091124120059.jpg.

That way you could avoid to delete the images when updating. However, you would leave a trail of old outdated files...

HakonB
I might very well end up having to delete the cached files when updating the database row, but I would still prefer to keep those two concerns separate; my "dumb" image options model shouldn't need to know about my caching mechanism.As for leaving a trail of old images, that would be a big problem.Furthermore, the image options are actually changed quite a bit right after the image is uploaded, since the changes are committed incrementally (over ajax).
Daniel Schierbeck
Why not add an OnTransformationUpdate event to your image options model? Then your cache solution could hook into the event and delete the appropriate cached image.
ebrown
ebrown: The cache solution is running on different servers, and the web server, which handles uploading the image and updating the options in the database, runs a mix of ASP classic and ASP.NET -- and is architecturally unsound. I'd like to keep these parts separate.
Daniel Schierbeck
+1  A: 

Why not run the process to generate the physical image whenever those settings are changed, rather than on each request?

Sohnee
I'd like to keep my image uploading code as dump and simple as possible. It should just push the images to the image servers.
Daniel Schierbeck