finalize_update -- why touch the assets?

295 views
Skip to first unread message

John Trupiano

unread,
Jun 5, 2008, 3:20:33 PM6/5/08
to Capistrano
Hey Jamis,

I can't understand why we need to touch all of the asset files after a
re-deploy. If I understand it correctly, rails uses the last modified
date on an asset to append the querystring value. As such, this last
access date would change if a file was changed, but would otherwise
remain the same. What then is the need to go ahead and dirty all of
the assets?

It seems to me that we're unnecessarily asking clients to re-download
all of our assets, even those that haven't changed. Am I missing
something here?

Thanks.

-John

Jamis Buck

unread,
Jun 5, 2008, 3:22:39 PM6/5/08
to capis...@googlegroups.com
It is so that the timestamps are all the same, across all of your
servers. If the timestamps are even a second off (which can easily
happen when you are deploying to multiple servers), then the client will
have to download the assets again every time their request hits a
different server, which totally defeats the purpose.

- Jamis

John Trupiano

unread,
Jun 5, 2008, 3:24:50 PM6/5/08
to Capistrano
Makes sense-- thanks.

-John

John Trupiano

unread,
Jun 5, 2008, 5:30:09 PM6/5/08
to Capistrano
Actually, I'm still a little confused by this. Doesn't your SCM
dictate the last accessed timestamp? In other words, if your app is
checked out to several different app servers, shouldn't the timestamps
all come from the same authoritative source (the SCM)?

Am I (a) misinterpreting which file attribute is used by rails to
create the querystring param, or (b) misunderstanding how the last
modified timestamp is determined when checking code out of a
repository?

-John

Jamis Buck

unread,
Jun 5, 2008, 5:56:02 PM6/5/08
to capis...@googlegroups.com
I've not seen an SCM that preserves timestamps on checkout, but that
might just mean I'm doing it wrong. In practice, though, we (at
37signals) are seeing files being stamped with the time of checkout, not
with the time of last commit. This means that when checking out files on
multiple servers, if one server takes a little longer to comply with the
checkout request, the timestamps are off.

Now, if this is me doing something stupid, please correct me. I
certainly don't claim to be an expert in these matters. But the mass
touch of asset files on deploy was how we worked around it. I certainly
would be the last to complain if someone found a better way. That touch
command drives me nuts.

David Masover

unread,
Jun 6, 2008, 6:00:37 PM6/6/08
to capis...@googlegroups.com
Clients should be using ETags anyway...

That said, even if an SCM doesn't preserve timestamps, it should at least be able to tell you when a particular file was last modified, and which files have been modified since a particular revision. It'd still involve a touch, but it'd be more accurate -- only changed files would appear as changed, which is what you want.

John Trupiano

unread,
Jun 7, 2008, 12:14:16 PM6/7/08
to Capistrano
Looking into Subversion specifically, it definitely behaves as you
described Jamis. An interesting idea would be to write a post-commit
hook that added a last-edited timestamp as a property on the file.
This would allow us to avoid this.

That said, that solution targets a specific SCM, and for it to work
with Capistrano, you'd need this subversion post-commit script.

What's terribly annoying about this is that Subversion does in fact
record the last modified timestamp. Running svn info on a file will
give this information back to you. I think it's ridiculous that
export and checkout don't allow the option to preserve this timestamp.

-John

John Trupiano

unread,
Jun 7, 2008, 12:38:27 PM6/7/08
to Capistrano
Ah ha! Found it in Subversion. There is a global configuration
option use-commit-times that by default is turned off. This is a per-
host setting (and can be overridden by local user preferences) so this
means that it would part of your initial server setup. In other
words, after installing Subversion, you would set this global config
parameter.

=========================
From the SVN manual:
=========================
use-commit-times

Normally your working copy files have timestamps that reflect the
last time they were touched by any process, whether that be your own
editor or by some svn subcommand. This is generally convenient for
people developing software, because build systems often look at
timestamps as a way of deciding which files need to be recompiled.

In other situations, however, it's sometimes nice for the working
copy files to have timestamps that reflect the last time they were
changed in the repository. The svn export command always places these
“last-commit timestamps” on trees that it produces. By setting this
config variable to yes, the svn checkout, svn update, svn switch, and
svn revert commands will also set last-commit timestamps on files that
they touch.

=========================

Capistrano could now expose another property to set...something like
'dont_touch_assets' (probably a better name). The onus would be on
the app writer to know that he has set up his server's subversion
configuration to do just this. Then, in finalize_update, this
property could be queried, and the touch process could be conditional.

Any interest in a patch? Also, any suggestions on a good name for the
property?

-John

Jamis Buck

unread,
Jun 7, 2008, 2:08:25 PM6/7/08
to capis...@googlegroups.com
Good find. I'm not opposed to another variable; there's already one for
determining whether or not to make the checkout group-writable. I'd
rather see the variable phrased as a positive, than a negative,
something like "normalize_asset_timestamps" and have it default to true,
much in the same way that "group_writable" is used.

John Trupiano

unread,
Jun 7, 2008, 3:35:35 PM6/7/08
to Capistrano
I sent you a pull request on github for this-- I'm still getting my
feet wet with git, so let me know if I did something wrong.

-John
Reply all
Reply to author
Forward
0 new messages