--- date: "2007-10-15T06:16:32Z" title: 'Brain Dump: Random Migration Notes' ---
I've been using the migration and some recent side projects as sandboxes to try out new things. Here's a semi-random list of useful tidbits I've picked up along the way:
Better mod_rewrite magic: Google turns up plenty of mod_rewrite examples on automatically stripping the dreaded "www." prefix from URLs. Unfortunately, most of them appear to be incorrect. Here's the most common solution:
RewriteCond %{HTTP_HOST} ^www.example.com$ [NC]
RewriteRule ^(.*)$ http://example.com/$1 [R=301,L]
What it's supposed to do is redirect visitors from
http://www.example.com/whatever to http://example.com/whatever,
but what it actually does is redirect visitors to
http://example.com//whatever. It's minor, but it was driving me
nuts (Arrrrrrr). Anyway, here is the correct solution:
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteRule ^/(.*)$ http://example.com/$1 [R=301,L]
mod_deflate: Saves a ton of bandwidth, works great in IE7 and Firefox. The stock settings don't include a couple of common MIME types; here's the list I'm using: text/html text/plain text/xml text/css text/javascript application/x-javascript text/csv
ExtJS Builder: I decided to test the ExtJS builder for a personal project. The interface is a bit finicky; it took me about 5 tries to get all the dependencies for my project selected. Here are the results:
| File | Minified | Deflated |
| ext-all.js | 468k | 125k |
| ext-mine.js | 276k | 77k |
Note: The "Minified" column is the total file size after being shrunk with Douglas Crockford's
excellent jsmin, and the "Deflated" column is
the actual transfer size (according to Firebug) after being passed through
mod_deflate.
Not too shabby for 20 minutes of work. I'm a little bit disappointed by the stock mod_deflate compression ratio, so that may need a bit of tweaking.
Backgrounding Mercurial Hooks: The Mercurial book has an excellent
chapter on hooks. What it doesn't mention, unfortunately, is how to
run hooks in the background. I have a semi-lengthy outgoing hook
(roughly equivalent to a client-side post-commit for you Subversion
weenies) that connects to a web server via ssh and performs some
deployment tasks, and all attempts at backgrounding a shell script
eluded me. Well, it turns out Mercurial has an extra hidden file
descriptor that has to be closed in order to background a hook. So
here's my down and dirty client-side background deployment hook:
#
# outgoing hook script that connects to web server and deploys
# the latest site from tip. It is run in the background after a
# successful 'hg push'.
#
# options
opt = {
# remote hostname
'host' => 'web',
# remote command (relative to my home directory)
'cmd' => 'bin/update_site.sh',
# client-side log (set to /dev/null to disable)
# 'log' => '/dev/null',
'log' => '/tmp/site_update.log',
# delay (in seconds) before update
'delay' => 3,
}
# fork and run update in background
pid = fork {
# close stdin, stdout, and stderr
$stdin = $stdin.reopen('/dev/null', 'r')
$stdout = $stdout.reopen(opt['log'], 'a')
$stderr = $stderr.reopen(opt['log'], 'a')
$defout = $stdout
# close all other file descriptors
# NOTE: mercurial appears to have a hidden fd laying
# around somewhere, so this evil is necessary...
(3..99).each { |fd| IO.new(fd).close rescue nil }
# wait for push to finish
# (this should poll the hg server instead, to handle
# lengthy pushes)
sleep opt['delay']
# run update command and exit
args = ['ssh', opt['host'], opt['cmd']]
exec(*args)
# never reached
exit 0
}
# reap child and exit
flags = Process::WNOHANG | Process::WUNTRACED
Process.waitpid(pid, flags)
Update: Markdown really mangled my markup this time around. Usually it's pretty tolerant, but apparently this post was just a bit too much. Oh well...