Random Passenger Observations
Played around with Passenger (v1.0.4) a bit more last weekend. Deployed a Radiant instance with it for staging. Overall, quite happy. However, thought I’d take the opportunity to jot down a few observations:
First, Radiant, with a smattering of extensions, takes a while to start up on the vhost we’re playing around on (yes, need to pump up those specs before deploying anything real). Since Passenger cleans up idle Rails instances when they fall into disuse, this can mean a harsh initial request delay for infrequently accessed hosts.
Passenger has clearly targeted the shared host market, where hosts have a large memory footprint and a large number of applications. The same strategy doesn’t work quite as well for a small VPS memory footprint and a single application root, where it would make sense to keep an instance in memory at all times (and clean it up and respawn it, perhaps, on occasion if an idle timeout is reached).
The solution in this case is to increase the Rails pool idle timeout to something that matches your traffic profile (of course, the tradeoff there is with the growing memory footprint of long-running processes…). And while you’re at it, adjust the maximum number of spawned instances—it defaults to 20, which is great for a dedicated with 2GB but not so good if you’re running a single application on a 512MB VPS.
More information is available in the architectural overview and the excellent user guide that the Phusion guys have put together. The SpawnManager itself is written in Ruby, and has a set of RDocs that you might want to take a look at as well.
We initially had some process ownership issues, where the Rails production log wasn’t being written to. The Rails server instance is going to be running as whatever user owns config/environment.rb (unless you change this in the config), so make sure to chown/chmod appropriately.
Finally, the restart mechanism, although a bit odd, is pretty useful. If you touch a file called restart.txt in the #{RAILS_ROOT}/tmp directory, it’ll reload the application instance on the next request without having to explicitly restart apache. Here’s a Capistrano deploy:restart task for this:
namespace :deploy do
task :stop, :roles => [:app] do
puts "Use the deploy:restart task to restart the Rails application"
end
task :start, :roles => [:app] do
puts "Use the deploy:restart task to restart the Rails application"
end
task :restart, :roles => [:app] do
run "touch #{current_path}/tmp/restart.txt"
end
end
Note To Self (Good Examples Are Hard)
The single hardest thing about writing a book, I’ve decided, isn’t the writing part. It certainly isn’t the technical part either. I don’t mean to downplay my own skills or those of any other technical author, but the truth is that you don’t have to be a guru to write a fantastic book (it does help, of course).
The key to writing good book material is being able to show people how to do things while keeping them entertained. That means coming up with examples that tread the line between being practical, being appropriately demonstrative, and being correct. Good examples are the hard part.
When developing an example, you’re trying to come up with something that has the following characteristics:
- It’s interesting. That is, it’s worth writing about in the first place. No one wants to read another blog post creation example (unless there’s something unusual about it). BORING.
- It represents best practices. You’re an author. You have to be right. Or at least able to competently defend your implementation choices, anyway.
- It illustrates those concepts that you’re trying to write about. This should be first point, rather than third. See what I mean?
- It minimizes focus on those elements that you are not writing about. That is to say, we shouldn’t spend a lot of time talking about fuzzy bears, even though there are many different types of fuzzy bears, six species of which are listed as vulnerable or endangered by the World Conservation Union (whose headquarters are in the scenic Lake Geneva area of Gland, Switzerland).

The last point is a tricky one, but it’s important. You have to cut corners when creating good examples—but not the important ones or the ones that would prevent it from representing best practices. If you’re trying to illustrate, for example, how to build a tag cloud, you don’t want to spend lots of time on the CSS for making it pretty. Leave that to the CSS books.
If your example involves video transcoding, and the point is to illustrate the use of a message queue, you’re going to be really tempted to spend an extra 2-3 pages on certain format discrepancies or operational edge cases but DON’T. It’s interesting, sure, but if it’s not central to what you’re currently trying to demonstrate (message queues). You must resist.
If your example is a simple web service for sharing geographic location data and you’re using a bunch of RESTful conventions, make sure to explain the basic concepts. But don’t write a dissertation on REST vs SOAP. And don’t worry about responding to formats that aren’t part of the main example.
Just because it’s how you’d do it in a real-life project doesn’t mean it’s how you’d write about it or explain it to others. Keep it simple, lively, and (as Gold Five so succinctly put it before crashing his X-Wing) stay on target.
Music To Code By
There’s a good thread going on over at Hacker News today regarding music for coding sprints. It’s interesting to see that a number of people, like me, have trouble concentrating when listening to music with prominent lyrics, whereas others thrive on it.
A lot of people also seem to really dig electronica. I guess that’s no big surprise. It’s never done much for me, personally, although there are a few electronic pieces I do really like (NIN’s Ghosts being a recent example). Being an ex-hc/metalhead I gravitate more towards melodic post-rock stuff and the occasional poppy masterpiece.
Here’s some stuff in my current work playlist:
- Explosions in the Sky
- Mogwai
- Castor
- My Bloody Valentine
- Elliott
- Pinback
- Isis
- On The Might of Princes
- Jesu
- Portishead
- Dredg
- National Skyline
- Pelican
- Low Frequency In Stereo
- Radiohead
- There Were Wires
- Godspeed You! Black Emperor
- Mouth of the Architect
Yes I know some of these bands have lyrics. But they’re so fuzzed up or unintelligible that my brain doesn’t seem to process them while working, so all is good. And in the case of bands like Elliott and Pinback and Dredg, the vocals are prominent but somehow almost feel like more of an instrument. Also seems to work. Kind of strange, I guess.
NHRuby Hackfest
Yep, that's right. Hackfest tomorrow night in Portsmouth. Bring any code you're having issues with. Failing that, I've got a couple project tickets (DataMapper, Radiant) that we can dig into. We'll spend 30 minutes or so on a quickie mod_rails demo while we're there too.
In other local news, John Herman has been swell enough to put together an NH Media Makers group. The first get-together is May 11th at Crackskulls in Newmarket. Rock out.
Mod_Rails Revealed
The hardworking hackers over at Phusion finally unveiled Passenger (mod_rails) earlier today. I just moved one of our staging servers over to it and will be playing around with it a bit more over the weekend. So far I'm happy to report that, as advertised, it's dead easy to use... and the performance seems solid.
I'd write up a tutorial but honestly it's so simple that it's completely unnecessary (imagine that!). Check out the updated screencast for all you need to know to get up and running and make sure to dig into the provided docs if you need more. They're very thorough.
In summary, it's great to see more Rails deployment options emerging, and it'll be interesting to see viable shared hosting options for the low-end market too. Although I'm a strong believer in the app server + frontend web server pairing, there are a whole class of applications for which it just seems like overkill.
A hearty 'nice work' to everyone involved! Now where's my mod_rack? :-)
UPDATED 4/12: this blog is now running on mod_rails and Mephisto 0.8!
2008 Rails Rumble Rumors
Just to clear up any possible confusion on that matter: Yes. There will be a 2008 Rails Rumble. And no. It will not be in May. Probably September or October.
We have a lot of great ideas (thanks to everyone that participated and commented) that will improve on last year’s experience dramatically and the whole team is looking forward to it, in a big way. More information coming soon, I promise, as well as an announcement, new blog, and specific details prior to Railsconf.
Oh, and speaking of Railsconf… Josh Owens, of TastyPlanner fame (last year’s grand prize winner), is giving what looks to be a fun talk about their experience building a kickass app in a 48 hour timeframe. If you’re going to be there, you ought to check it out. Especially if you’re interested in participating this year. If you haven’t yet registered for the conference, you’re running out of time, so get to it.
See you there!
Radiant Super Multi Go!
Here at Ubikorp we've used Radiant as the basis for a number of client projects who needed core CMS-like functionality. As anyone who's played with it knows, Radiant is very barebones; this is intentional and a welcome change from most packages, which attempt to throw the kitchen sink of clutter at each and every problem. Fortunately, it's easy to build on top of the basics by using a well thought-out extensions system -- there are a large number of stock extensions available (and it's also really easy to roll your own for custom app logic).
One of the more interesting extensions is the multi-site extension. To be honest, multi-site capability is something I really feel should be a core feature, but since it's not, this approach works surprisingly well (at least until you start adding other extensions that would ideally be multi-site-aware). Radiant school headmaster Sean Cribbs wrote an initial version of the extension back in November, but it didn't quite work for us on a particular project -- we needed to be able to scope individual user-level access to particular sites. So we extended it, and thus the scoped multi-site extension was born.
Well, actually, it's just a fork of the multi-site plugin. For now.
Features:
- scopes user level access to individual sites (admins and developers still have access to all sites)
- regular users can't see, edit, or access other user sites that they don't own
- optionally scopes layouts to sites
- snippets usable everywhere, but display and editing of snippets limited to admins/developers
Anyway, if you're interested in seeing our changes you can check it out on github in my fork of Sean's Radiant repo. Is this a candidate for integration into the existing extension, or should we spin it out as a separate extension? Let me know what you think.
Twittering
I've been bitten by the Twitter bug. I know, I'm a little late to the party. But being late is fashionable. And I sure like the fashion.
Anyway, go ahead and stalk me. If you dare. Or check out the status updates in the blog sidebar if that's what you're into. I've also added my DDJ blog feed to the sidebar. A couple of my recent articles:
- Roll Your Own Web Framework (an introduction to Rack)
- Rails: Vendor Everything Just Got Easier (the new config.gem features in Rails Edge)
More soon. Promise.
DDJ Code Talk Launches
The legendary Dr Dobb's Journal just announced the launch of their new blog and forum system, DDJ Code Talk. I was extremely honored when Jon asked me to contribute, as DDJ has long been one of my favorite industry pubs. Them peoples is hardcore.
In the coming months I'll be contributing articles about Ruby, web application development, and lightweight languages. Head on over to check out my first article for them, a quick survey of Alternative Ruby Web Frameworks. There are a few other Ruby geeks hiding in their trees too, and a broad range of topics, including Python, Java, .NET, D (!), databases and web service architecture and design. Thanks for reading!
NHRuby: Django/Rails
If you're in the ME/NH/MA area on Tuesday, make sure to stop by the NH Ruby SIG; Brian Turnbull will be presenting an in-depth talk comparing the philosophies of Rails and Django. I've never done any Python work at all myself, so I'm really looking forward to this dissection.
If you're not in the area, you're still in luck. We're trying something new this month, and will be broadcasting the event live via WebEx. Big thanks to Tim Golden and our sponsor RMC Research for hooking this up!
(NOTE: we usually meet on the third Tuesday of the month, but our host had some scheduling problems this time around; we'll be returning to the normal schedule in April)
Git Ur Radiant Extensions
I published a new Radiant extension yesterday: Database Form. It provides a new page type and tags for constructing contact and request info forms and will save user responses to a database table. Those responses can then be exported for use in another application (CRM, etc). See the README for usage and examples. It was extracted from some client work that we'll be deploying soon.
If this sounds good, you can download or clone it from GitHub. While you're there, spend a few minutes poking around; GitHub is pretty dang cool. They've definitely succeeded in making Git repository hosting stupid simple. Just click a button to create a project, follow a few commands on your local system to import your sources, and you're off and running. You can then view the repo history, browse the source, see diffs, download a tarball (for easy extension installation in your pre-existing Radiant project), and fork it if you want to add your own features. That's where things get sweet, of course: Fork the project, make some changes, and send me a pull request so we can merge them into the master branch. All this is possible without GitHub, but it sure does a swell job of streamlining things and abstracting the suck away.
It also exposes the links between developers and their project contributions in a pretty cool way. See the DataMapper project's "network" page to see what I'm talking about. Ryan Tomayko has pointed out that this sort of interaction starts to smell an awful lot like a MySpace for developers, where lines in the social graph are drawn based on OSS project work. Wow, that's a cool thought, ain't it?
Principle of Least Surprise
One of the things I love about Ruby is that it tends to follow the principle of least surprise; things just work the way you would expect them to, with precious few exceptions (cough cough inject cough). Horray for intuitiveness.
On the other hand, I've become so spoiled by The Principle that willful violations stand out like the sober guy at the all-inclusive beach resort. I know I'm being a nitpicky ass here, but this Rails bug^H^H^H ticket makes me kinda ill. Funny, because in my previous life as a Java/PHP developer, I wouldn't have even batted an eyelash at it.
OpenID + Client Certs = Win
I'm a big fan of OpenID. Or rather, I'm a big fan of what OpenID and data portability mean for the web at large in the coming white days. Single sign on and distributed identity is certainly an idea that's been long overlooked and it's time that we changed that. The next time you write a web application, ask yourself: "do my users really need yet another set of login credentials?". Then implement OpenID. It's really simple, especially in Rails. I gave a presentation on it at NHRuby last month (download PDF).
So, as gah-gah as I am over single sign on for ease of use, I'm a embarrassed to note that, like almost everyone else, I've completely overlooked client certificates for web-based authentication. By using client certificates you one-up single sign on by removing the need to use a login/password at all. This isn't new; it's something that's been available in every web browser for pretty much as long as anyone can remember. And yet I've never, ever seen a site that supports them for an authentication mechanism. Sad faces abound.
But wait! OpenID to the rescue! It turns out that MyOpenID (and a host of other OpenID providers) DO make use of them. So if you create a client certificate with your OpenID provider, you can eliminate the need to use a login/pass with any OpenID client sites. Cheers to Dr Nic Williams for digging this up. Sometimes old (and ignored) is the new new. Rock on.
More details at Dr Nic's blog.
Plugins Are Unnecessary
Plugins really are unnecessary -- Jay Fields is absolutely right. RubyGems is a great package management system and there's no reason it can't do double duty here, if we just impose a few extra restrictions on Gem/Plugin structure. There are other benefits too using Gems too, such as versioning and dependency management, which is somewhat painful in the world of Rails plugins.
Merb already uses Gems for plugins/extensions. Why doesn't Rails? Historic reasons, most likely. Rails itself predates the existence of Gems iirc. But seriously, how hard would it be to rewrite script/plugin to install a gem and unpack it into vendor? That's the first step.