Thursday, May 15, 2008

Team Build's 'Get' always writes files with the current date

We use Team Build for all of our builds including the packaging of our Static Content application. When Team Build does a 'Get' of Sources it writes the files with the creation/modify date of the current build time. For example if I checked in a file (e.g. Mac.jpeg) yesterday (5/14/08), but didn't run a Team Build until today, the file date would be today (5/15/08). For most things this is not an issue, but for Static Content it is.

The reason having the current date/time on Static Content is an issue is because of the way the browser caches things. When a request is made to our site(s), the browser will see that we have images (e.g. Mac.jpeg). Before grabbing the image from the web server the browser will check its local cache. If the image in the local cache has the same modify date as the image on the web server, the image is not requested, thus improving performance. However, if the local cached version of the image file is older than the web server's version, the new image is sent to the requested user.

The issue is, because Team Build always writes the files with the current date (e.g. 5/15/08), when we deploy them to the Static Content servers they all look like updated image files. This is bad as it invalidates ever user's cache and thus slows down our application as every image is sent to the user.

I've read a bunch of things on this and from what I've heard, the TFS Product Team might be looking into a fix for this. I've dropped our local Microsoft rep a note asking him if he had any details about that. I've also found this post from Cory Foy which looks like a custom task we might be able to write in order to get the behavior we need. If I get any word back from my Microsoft contact, I'll let everyone know. In the mean time, we are looking into Cory Foy's approach.

I'm also going to drop a note to the good folks over at Teamprise to get their input. We're using their Ant interfaces to TFS for some of our non-Microsoft builds and thus could have a similar issue.

5 comments:

Buck Hodges said...

You can elminate this largely (or perhaps entirely, depending on your point of view) by setting the IncrementalGet property to true in your tfsbuild.proj file in TFS 2008.

http://blogs.msdn.com/buckh/archive/2007/07/24/tfs-2008-some-properties-that-you-can-use-to-customize-your-build.aspx

Buck

Unknown said...

Also, have a look at the "Team Foundation Server Properties" spec for Rosario:

http://msdn.microsoft.com/en-us/vstudio/bb936702.aspx

Mac Noland said...

Thanks Buck! I think that we'll take a look at your suggestion. However, I do see issues with it in our environment. We have a 20 build server VM farm and periodically like to refresh them all so the build environment(s) are pristine. The incremental get will only be good up until we decide to reload all the build machine templates (which wipes the machines clean). Now we could add an exclusion and say "refresh all build server except the one we use to build static content," but that seems fragile to me.

Grant, I took a cursory look at the document you suggested. To be honest, I'm having some trouble understanding it (which is no surprise ;)), but are you basically suggesting that in Rosario we'll be able to query system "Properties" (or user Properties we define) and use those as part of our Source Control interaction. So for example, we could write a <Task to get a file's Changeset "Date" property and then use that to reset the file's modify date?

Being a dumb user, I'd actually prefer some parameter we could put in the command line (e.g. .\tf get MyFile.cs /KeepModifiedDate) or a Property we could set in Team Build <KeepModfiedDate>. What are you thoughts about something like that?

Unknown said...

Have you found a good solution for this particular problem?

I've contacted our Microsoft premier support, but dont expect much help. They will, probably, refer to Rosario :(

Mac Noland said...

Hey Alex! Thanks for the question.

Nothing as of yet. however, I'm guessing we'll write a custom Task like Cory did. http://www.cornetdesign.com/2007/12/fixing-timestamps-on-files-from-team.html

I'd recommend the same.