Harnessing Capistrano

These are my notes from Jamis Buck’s tutorial on Harnessing Capistrano, all in bullet form.

  • Focus here is on Capistrano 2.

  • Capistrano came from a need. Basecamp was running on one machine and scaling to a second machine made deployment painful.

  • Adhoc monitoring — for checking uptime, disk space, grep logs, status of db slaves — on every server on the cluster.

  • Server maintenance: package management, synchronising configuration files.

  • 2.0 preview: gem install -s http://gems.rubyonrails.com/ capistrano but you must have the prerequisites installed first (net-ssh, net-sftp & highline).

  • Requires a POSIX (*nix) target, ssh access & ssh keys (or identical passwords on all your servers).

  • Capistrano config is now called ‘Capfile’, is a ruby DSL similar to Rake’s DSL, but it’s not the same.

  • set :gateway, 'internet.accessible.machine' will allow you to talk to servers behind a gateway, so the actual app servers aren’t necessarily directly accessible.

  • cap -T (which used to be cap show_tasks) doesn’t show tasks which don’t have a description. So we can hide ‘internal’ tasks which are only called by other tasks.

  • Use cap invoke to run arbitrary commands on remote systems. Doesn’t even need a Capfile if you specify everything on the command line. For example cap HOSTS="app1,app2" COMMAND="tail /var/log/syslog" SUDO=1 invoke.

  • For running multiple cap invoke commands sequentially, use cap shell instead because it will cache the connection.

  • Capistrano 2 introduces namespaces. Woo! Syntax is the same as Rake. Introduces default tasks for a namespace called ‘default’. Eg, the deploy namespace has deploy:default which can be called by doing cap deploy.

  • If set is passed a block, that block is lazily evaluated the first time it is asked for by calling the block. The result is then cached for future uses.

  • cap -s foo=bar is equivalent to having set :foo, "bar" after all your recipes are loaded. cap -S foo=bar does so before recipes are loaded.

  • We have transactions. If a task fails, then the on_rollback handler is called for each of the executed tasks in reverse order. If the rollback handler fails, the whole world ends. Patches accepted!

  • Capistrano overrides ‘load’ and provides similar semantics, but it searches the directories in the load_paths variable. cap -f will load a specified file, but then won’t autoload the Capfile.

  • By default, capistrano is very verbose (-vvv). You can shut it up with -q.

  • Capistrano now has a “core team” with Mike Bailey & Ezra Z.

Deployment recipes

  • Assumptions: using source code control, you’re deploying a rails application, your production environment is all ready to go (dbs, web server, etc) and you’re using standalone fastcgi listeners.

  • capify . creates a minimal Capfile and a basic config/deploy.rb. The Capfile only loads the deployment recipes and the config/deploy.rb.

  • The deployment recipes in cap 2 are now opt-in so that there’s less noise for folks using it in non-deployment scenarios.

  • Capistrano 2 can check for dependencies before deploying — do the appropriate directories exist, is subversion installed? — done with cap deploy:check. Some deps are local, some are remote. We can customise these. Wow, this is neat: depend :remote, :gem, 'tzinfo', '>=0.3.3'

  • For fcgi listeners, still need script/spin to tell capistrano how to start up your app from cold. Can just call script/process/spawner with the appropriate args.

  • 37Signals have started using process supervision (didn’t specify whether it was init/svscan/runit) to keep an eye on their fcgi listeners. Recommends you get your app working before you start messing with it, ‘cos it requires a bit more upfront configuration.

  • Cap 2 introduces deployment strategies which encapsulates the mechanism by which the source code is acquired. Default is ‘checkout’ which will check out a copy from your scm repository. ‘remote cache’ sounds pretty useful to me, which uses the scm repository but caches what’s checked out, so the checkout becomes svn up which should be a bit faster. Controlled by set :deploy_via, :whatever.

  • Volunteers sought to write a CVS scm backend instead of just promising to. Or maybe nobody really uses CVS any longer. :)

Advanced Techniques

  • In cap 1.4 we had single hook tasks before and after each task, eg after_symlink. Trouble was that third party libraries stomped over each other’s after_symlink. Now we have before :task, :do_stuff and after :task, :do_stuff. Better still, these are just wrappers around the generic callback mechanism on. I guess before is on :before, :do_stuff, :o nly => [ :task ] or something like that?

  • Nick the configuration for staging environments from the slides! Yeah, that looks pretty neat.

Upgrading to Cap 2.0

  • With cap 1 & 2 installed, to use cap 1, do cap _1.4.1_.

  • 3rd party extensions and libraries need to be rewritten. For example, mongrel_cluster ain’t gonna work yet.

  • Actor has disappeared and has been subsumed into the Configuration class.

  • If you’ve overriden or extended tasks, you’ll need to figure them in with namespaces. If you used before_task and after_task you should be mostly OK, though.

  • Compat mode to aid the transition. Do cap -Ff compat or load 'compat' to load it. Mostly it’s there to help you learn what the new namespaced task names are.

  • cap -Ff upgrade gives you the upgrade:revisions task which will create #{release_path}/REVISION retrospectively for existing deployments.

  • The render helper has disappeared.

RailsConf 2007: Is Javascript over-rated?

The first tutorial of the weekend I signed up for was “Is Javascript Overrated? (Or how I learned to stop worrying and love Prototype & script.aculo.us)”. I never quite get around to doing enough JS work, instead finding other willing victims colleagues who are more into that kind of thing. But I’m definitely interested in being able to do more of the front end UI myself. So, I figured this tutorial would be useful.

Checking out my notes, I’ve discovered a few bits and pieces about Prototype & script.aculo.us that I didn’t know before. The highlights would be:

  • $$ has full support for CSS 1, 2 & 3 selectors. eg $$('table tbody > tr:nth-child(even)').invoke('addClassName', 'even') will select every second row of a table and give it the class ‘even’. Neater than doing some cycle type thing.

  • New with 1.5: DOM traversal. $('id').down() picks the first child, $('id').up() picks the parent. next() and previous() pick siblings. $('id').descendantOf('parent_id') returns a boolean.

  • $('form').focusFirstElement() does exactly what it says on the tin.

  • The form validation demo code he showed off looks really neat. It makes use of a (non-strict-HTML) format attribute, then does some validation on onsubmit. The actual validation functions are all added to the appropriate Element subclasses. Very neatly done. I’m wondering if anybody has done some work to integrate this with Rails model validations and make it more robust…?

  • Official JSON library breaks Prototype enumerables, so don’t use it! Doesn’t matter because Prototype implements everything anyway.

  • transition option for effects determines the function used to affect the dx/dy of the argument passed in to update. Apparently, sinoidal looks more natural for moving effects than linear, so that it accelerates & decelerates.

  • New in scriptaculous 1.7: Effect.morph() which will change from existing CSS styling to a newly specified one over a period of time. For example, grow a font size or move items around. Difficult to explain, but it looks pretty sweet. :) Best to use for mocking up an effect, because it has performance issues from parsing the CSS.

  • Firebug will actually show you the transitions happening (delayed, though). Inspect the element, then run the effect, and Firebug will show you the style attributes changing, highlighting them in yellow as they change.

  • Effects have an inspect() function to use from the Firebug console.

  • Element.addMethods() to put custom effects on elements (so that you can just do $('id').customEffect()) looks pretty powerful.

Umm, that’s about it, I think. To be honest, I was a little disappointed — the tutorial was pretty low bandwidth and didn’t introduce much I couldn’t have found by looking at the manual. Then again, I’m not sure what I was expecting…

One question I’d meant to ask since he mentioned it: Is there an idiomatic way of having an initialize() method in a subclass which calls the initialize() from its parent class? (The equivalent of doing super in Rails.) I’m not too fussed about a generic solution that works for every method, but one that at least works for initialize would be good.

RailsConf Europe 2006: First Plenary — DHH

This is the first in a series of articles of me writing up my notes from RailsConf Europe 2006. They are all first drafts, probably technically inaccurate and slanderously misquoting people. Let me know and I’ll fix them. You can follow this series of posts by looking at articles in the RailsConf Europe category.

Exciting news: Rails 1.2 is nearly ready for release. A release candidate should be up on gems.rubyonrails.org by now. New features include:

  • The dependency system has been changed and is apparently now more coherent. One useful outcome is that modules will now reload too when they change in development.

  • The routing code has been rewritten. Speaking from the perspective of somebody who’s tried to work through the existing routing code, I say “yay!”

  • Restful stuff for the controllers.

  • A deprecation system. And anything that’s marked as deprecated in 1.2 will be removed in 2.0. Very opinionated, but a really good idea IMHO.

The next release after 1.2 will be 2.0. 1.1 was about getting ActiveRecord ‘right’ and imposing conventions so that people all use their models in a consistent manner. 1.2 is doing the same to the controller. 2.0 will be tackling the view.

Simply Restful

Nice URLs and full use of HTTP verbs turned out to be a minor feature of the simply restful work. The main feature was that controllers now have a convention imposed upon them, meaning they will all look the same (or at least similar) and developers can focus on more important things.

There’s going to be a new scaffold (don’t know if it’s landed yet, but DHH did demo) in 1.2 which uses the new restful style. It still looks butt-ugly, but that’s the point! Scaffolds are just that, a quick starting place for getting in data. You’re meant to customise, or completely replace them as you develop a site. script/generate resources_scaffold will generate a controller, model and migration for you, and add a resource map to config/routes.rb.

The scaffolding code also uses respond_to and will generate XML out of the box. In addition to the current respond_to behaviour where it looks at the HTTP Accept: header, it will interpret extensions as wanting a particular type. For example, asking for http://localhost/posts.xml will call the index action on PostController and respond_to will indicate that you’re looking for an XML response.

There are unresolved decisions with respect to the restful controllers. In particular, what should the convention be for searching? A separate action? Or parameters passed to the index action?

Active Resource

It’s just like ActiveRecord, except it uses an HTTP backend, talking to another web service. If you follow the restful conventions on your controllers in the application providing the data, then you’ll get this functionality for free. It was extracted from 37Signals’ desire to have their applications interact with each other, and with other internal admin apps. Active Resource will not ship in the 1.2 core, but will be available as a plugin. CDBaby.com are already using it in production and 37Signals will be shortly.

Simply Helpful

This was a completely new one to me. Simply Helpful is all about adding conventions, and cleaning up, the view. It’s not designed to get the yellow fade technique on every site in the world ever. (Like they need help making that happen!) A lot of the work is about DRYing up the repetition in views. For example, a div showing a post might look somethingg along the lines of:

<div id="post_<%= @post.id %>" class="post">
  ...
</div>

It’s a common idiom because you’ll want to style your post with CSS (hence the class) and you might want to manipulate the post with JS (hence the id). So how about we DRY that up:

<% div_for @post %>
  ...
<% end %>

That way the view code looks cleaner and it can be more about the model again. There are new conventions for partials too:

<% render :partial => @company %>

which is equivalent to:

<% render :partial => 'company/company', :o bject => @company %>

in current code. It certainly makes code more readable and imposes more conventions on naming of partials. There are similar improvements for rendering collections and forms. This code already works, is available as the simply_helpful plugin and is being used by 37Signals in their new Sunrise product. It does rely on code in edge (well, 1.2 when it’s released) Rails, though. It will be part of the core in 2.0.

My opinion

Just a random thing I picked up from all of these things: It seems that the convention we’re being told to adopt tends towards more of a 1:1 mapping between controllers and models. This isn’t a bad thing, but it’s not something I’d considered to be the case before.