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
tohttp://example.com/whatever
, but what it actually does is redirect visitors tohttp://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
- XCache: Fast PHP opcode cacher that actually works with recent versions of PHP. I tested several Wordpress, Gallery, and custom PHP sites without incident, and my (incredibly rough) benchmarks showed about a 4-7% increase in mean transfer speed.
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 throughmod_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-sidepost-commit
for you Subversion weenies) that connects to a web server viassh
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...