Friday, October 31, 2008

Capistrano Subversion password

Recently I ran into a problem with Capistrano asking for my password when performing a svn+ssh checkout even though I had my SSH keys configured correctly.

Capistrano hits the svn twice when performing a checkout. The first time it queries the most recent revision number and the second time to perform the actual checkout. It was during this second request that I was being asked for my password. After searching for awhile and trying multiple suggestions I finally came across a solution.

In app/config/deploy.rb :


ssh_options[:keys] = ["#{ENV['HOME']}/.ssh/id_rsa"] #Obviously needed
#default_run_options[:pty] = true #Didn't work for me
#ssh_options[:paranoid] = false #Didn't work for me
ssh_options[:forward_agent] = true #Ah hah.. Success!

Basically the ssh_options[:forward_agent] = true option forwards the first authenticated ssh session (the one that queries the revision number) to the second one (the one that performs the checkout).

If you are seeing the same problem this may just be the fix for you are looking for!

Wednesday, October 29, 2008

Quick Tip - Console Goodies

I just want to mention two quick little goodies for the rails console.

Tip #1 - Reloading

Have you ever been running the console and after modifying your source you notice that the console has not picked up your changes? This usually occurs when you adding/removing/editing associations on a model, messing around with your vendor or lib directory, changed an environment config or anything else that only gets loaded once.

Luckily there is a way to quickly reload your whole console environment without having to quit and restart saving you precious seconds. Actually when I used to develop in a windows environment starting up the console would take a very long time so this would save more than just a few seconds.


$ ruby script/console
Loading development environment (Rails 2.1.1)
>> User.first.posts
NoMethodError: undefined method `posts' for #<Class:0xb6f55a08>
# Now add the posts association on User
>> reload!
Reloading...
=> true
>> User.first.posts
=> [#<Post id: 1 ....>]

As you can see you just need to run the unsubtle command reload! to reload the environment.

Tip #2 - Sandbox

Have you ever want to muck around in your development database or dare I say production database and wished your temporary changes would not persist? Perhaps you wanted to test that new :dependent => :destroy association or perhaps you wanted to be evil (if only for a second) and destroy all the existing users just to make you feel powerful. Here's how to do it.


$ ruby script/console production --sandbox
Loading production environment in sandbox (Rails 2.1.1)
Any modifications you make will be rolled back on exit
>> User.count
=> 214
>> User.destroy_all #Insert evil laugh here
=> [#<User id: .... ]
>> User.count
=> 0
>> exit

$ ruby script/console production --sandbox
Loading production environment in sandbox (Rails 2.1.1)
Any modifications you make will be rolled back on exit
>> User.count
=> 214

All you need to do here is add the --sandbox flag when starting up the console. Its basically like having a huge transaction block around your whole console session and by exiting you are throwing and exception and everything gets rolled back.

Tuesday, October 28, 2008

Delgation Pattern in Ruby

The Delegation Pattern is a common pattern in all OO programming languages and is generally preferred over the use of inheritance. The beautiful thing about Ruby/RoR is that there are many ways to go about implementing this pattern.

Say we have the following classes:


class User
attr_accessor :first_name, :last_name

def initialize(first_name, last_name)
@first_name = first_name
@last_name = last_name
end
end

class Whatever
def initialize(user)
@user = user
end
end

And for whatever reason we want to be able to access the object user's first and last name attributes from the object whatever like the following:


>> user = User.new("Rob", "Zotter")
=> #User:0xb7bf3b98...
>> whatever = Whatever.new(user)
=> #Whatever:0xb7bf1a14...
>> whatever.first_name
=> Robert
>> whatever.last_name
=> Zotter

Here are some ways to go about doing this.

Solution #1 : Wrapper Methods

We could simply add wrapper methods to the Whatever class that simply delegate the calls to the @user object.


class Whatever
def initialize(user)
@user = user
end

def first_name
@user.first_name
end

def last_name
@user.last_name
end
end

As you can see this quickly gets tiring as more and more methods are added to the User class that we would want to delegate. It also bloats the Whatever class.

Solution #2 : Method Missing


class Whatever
def initialize(user)
@user = user
end

def method_missing(method, *args, &block)
if @user.respond_to?(method)
@user.send(method, *args, &block)
else
raise NoMethodError
end
end
end

He were eliminate the need to continuously update Whatever class with wrapper methods when the User class changes by utilizing Kernel#method_missing. Now when the object whatever is sent a message that it does not know it will check the @user object to see if it responds to it and if it does it will delegate that method to it otherwise throwing a NoMethodError. Although this is an improvement over solution #1 it still has its drawbacks. First it is slower since it needs to search the whole Whatever class hierarchy before it reaches method_missing. Second, we do not have control over which methods can be delegated, they simply all get delegated to @user if @user responds to it. Third, whenever using method_missing it is always a little harder for anyone reading your source code to determine exactly what you are trying to do.

Solution #3 : SimpleDelegator


require 'delegate'

class Whatever < SimpleDelegator
def initialize(user)
super(user)
end
end

Here we are using SimpleDelegator which is an implementation of the Delegator interface. We just have to pass in the user to super during instantiation and all methods on user will be available on whatever. This is a little more transparent then using method_missing but by subclassing SimpleDelegator we are preventing ourselves from being able to subclass any other class in the future. We also do not have control over which methods get delegated. Lastly, this way uses inheritance to accomplish composition?!?

Solution #4 : Forwardable


require 'forwardable'

class Whatever
extend Forwardable
def_delegators :@user, :first_name, :last_name

def initialize(user)
@user = user
end
end

Here we are using the Forwardable module. We just have to simply extend our class with the Forwardable module and we explicitly set which methods to delegate using the def_delegators method. As you can see the first argument to that method is the object to which to delegate to and then the following arguments are which methods to delegate to that object.

Finally one last example using ActiveSupport#delegate which you get by default if you are running RoR.

Solution #5 : ActiveSupport Delegate


class Whatever
delegate :first_name, :last_name, :to => :@user

def initialize(user)
@user = user
end
end

This is very similar to the previous example but I prefer this over the former because I think it just reads a little nicer. In this example you list the methods to delegate first then you define what object to delegate to using the :to option. ActiveSupport extends Module with the delegate method so there is no need to extend the Whatever class before using it.

Solutions #4, #5 use metaprogramming techniques to dynamically add class methods to the Whatever class using class_eval which essentially make the class look like it does in solution #1.

As you can see there are many ways to implement the Delegation pattern in Ruby and I'm sure there are plenty more ways that aren't mentioned here. Like the old saying goes theres is more than one way to skin a cat and Ruby certainly gives you more than enough sharp pointy objects to do it with.

Thursday, October 23, 2008

Big Day for Amazon EC2

Today Amazon Web Services made some big announcements. We've been using AWS for over a year now and have been very happy with it.

* Amazon EC2 is now in full production. The beta label is gone.
* There's now an SLA (Service Level Agreement) for EC2.


Finally! This will make our customers and investors sleep better at night! It's nice to see something not in a perpetual beta.

* Microsoft Windows is now available in beta form on EC2.
* Microsoft SQL Server is now available in beta form on EC2.


Yawn... Microsoft in the cloud doesn't excite me much.

* We plan to release an interactive AWS management console.

I think the command line tools are just fine, but OK.

* We plan to release new load balancing, automatic scaling, and cloud monitoring services.


Oh Yeah! To me, this has been the last piece of the puzzle.

Load balancing in the cloud has been a "roll you own solution". The current solution is to use a software load balancer like HAProxy. However, this requires more machines, more management, and more hops and therefore more money. Round Robin DNS is a poor man's solution, do not even go there.

My wish list.

  • Better reliability than S3, please!

  • L4 load balancing

  • L7 content switching/filtering - Sticky Sessions

  • HTTP rewrite and compression

  • SSL acceleration

  • Cheap - cheaper than having small instances running a software load balancer

  • An easy web service API to configure all this

Kudos to the AWS team!

Monday, October 20, 2008

Ruby Syntax Highlighting in Blogger using Google syntaxhighlighter

In a previous post I used the syntax gem to get ruby syntax highlighting for this blog.

Well I just found a better way! Enter the syntaxhighlighter on Google Code.

It 100% Javascript based so there is no need to mess around with html yourself. Only drawback is that you need a place to host the files.

Getting it to work in Blogger


Go to Layout -> Edit Html and place the following right before the closing </head>.

<link href='http://.../stylesheets/syntax/SyntaxHighlighter.css' rel='stylesheet' type='text/css'/>
<script language='javascript' src='http://.../javascripts/syntax/shCore.js'/>
<script language='javascript' src='http://.../javascripts/syntax/shBrushRuby.js'/>
<script language='javascript' src='http://.../javascripts/syntax/shBrushXml.js'/>
<script language='javascript' src='http://.../javascripts/syntax/shBrushJava.js'/>
and then at the bottom after the closing </body> tag add:

<script language='javascript'>
//dp.SyntaxHighlighter.ClipboardSwf = 'http://.../flash/syntax/clipboard.swf';
dp.SyntaxHighlighter.BloggerMode();
dp.SyntaxHighlighter.HighlightAll('code');
//]]>
</script>

Then in your posting you just surround the code in a pre tag with the class name set to the language you are displaying:

<pre name='code' class='ruby'>
  ...
</pre>

The html above was put in a <pre name='code' class='xml'> tag. ;) Remember to escape your opening brackets with &lt;.

Now isn't that nice.

Sunday, October 19, 2008

Multiple rake tasks. Running rake tasks from a task

Rake is a very useful ruby build tool very similar to that of Ant for Java.

Sometimes you may want to run several rake tasks in succession and today I will go over several ways you can go about doing this.

Say we want to completely drop our existing database, recreate it and populate it with some sample data via a custom rake task called 'populate' (not shown here).

A naive way of accomplishing this would be to do the following:

 $ rake db:drop
(in /home/rob/project/)
$ rake db:create
(in /home/rob/project/)
$ rake db:migrate
(in /home/rob/project/)
$ rake db:populate


Besides just being horribly repetitive, this method requires you to wait to the completion of each migration before typing the next thus preventing you from grabbing the o so needed cup of coffee while your db is migrating. This method also reloads the rails environment before each migration which is completely useless and time consuming.

"Ok" you say, "I got the answer" and type the following:

$ rake db:drop && rake db:create && rake db:migrate && rake db:populate


This is one step better as you do not have to wait to the completion of each task before typing in the next, but we still have the problem of typing all of those commands as well as reloading the environment each time.

Sounds like its time for a custom rake task.
Lets create a rake file called db.rake and place it in our [project-root]/lib/task/ directory.

namespace :db do
task :everything => [:environment, :drop, :create, :migrate, :populate]
desc "Recreate everything from scratch including pre-populated data"
end
end


You can then just run one command

$ rake db:everything


For those of you familiar with Java you will noticed that the rake syntax of 'task :everything => [:environment, :drop, :create, :migrate, :populate]' is exactly like Ant's depends attribute.

For those of you not familiar with Ant ill quickly explain. Basically what 'task :everything => [:environment, :drop, :create, :migrate, :populate]' means is that the the task 'everything' depends on these other tasks so run those first.

Ok, so now we greatly improved our initial version in that we do not have to type all of the individual commands or wait for the completion of each task before continuing. We also get the benefit of not having to reload the environment before each task (other than the first time of course).

A problem arises though when we want to do anything else with this migration. For example, say we want to execute some logic or print out a simple message before and after each task execution. To accomplish this we would have to move all of the tasks out of the prerequisites section and move them into the actual task block. But how can we run another rake task from within a rake task? The Rake::Task api will help us find the answer we are looking for.

 task :everything => :environment do
desc "Recreate everything from scratch, including test data"
%w(drop create migrate populate).each do |task|
puts "Performing task #{task}"
#Some logic could go here
Rake::Task["db:#{task}"].invoke
end
end


The key to take out of this last example is the Rake::Task#invoke method. The method accepts a task (or tasks) and well... invokes it (or them).

So with the help of rake and Rake::Task#invoke we have a nice clean way of running multiple rake tasks.

Tuesday, October 14, 2008

Autotest notifications in Ubuntu, Mac and Windows

Autotest part of the ZenTest package is a great testing tool that will automatically run your RSpec tests when you make a change to any of the source files.

If you don't know about RSpec then you must have been living in a cave and I suggest you check that out first.

Today I am going to teach you how to setup automatic notifications in Ubuntu that will allow you to display the results of your tests in nice little window like so.



First make sure you have the libnotify binaries installed.

$ sudo apt-get install libnotify-bin

Then you'll need to install the actual autotest notification gem

$ sudo gem install carlosbrando-autotest-notification --source=http://gems.github.com

Easy enough. Ok now for the hard part of configuring it.... oh wait, did I say hard? I meant ridiculously easy.

$ sudo an-install

The above command will first backup then overwrite your ~/.autotest config file so you may just want to manually append the following if you have any existing configurations.

# ~.autotest
require 'autotest_notification'
SPEAKING = false
DOOM_EDITION = false
BUUF = false
PENDING = false
STICKY = false

As you can see there are a few extra options you can play with till your little heart is content. You can even get notified by voice if you install espeak and pass a '-s' switch to an-install.

An alternative to automatic notifications in Ubuntu is mumbles which you may want to check.

What about Mac and Windows?

The best thing about automatic notifications is that is fully compatible with Mac OS and Windows.

For Mac you'll need to install Growl and in Windows you'll need Snarl. Installation is just as easy but slightly different in these enviroments so consult the README.txt for detailed instructions.

Enjoy