Silverlight on Rails

03 Apr 2008

My “spare-time” project is to make a Silverlight plugin for Rails, which allows your controller/view code to either run on the server or the client. It's not available yet, but if you want it faster maybe making a big stink about it to my boss would work. Here's a messy contrived example of what you could do with it, but it makes the point.
class FooController < ApplicationController
  client :time

  def index
    render :text => <<-EOS
      <%= link_to_remote 'Show time', :url => {:action => 'time'} %>
      <br /><div id=”time_div”></div>
    EOS
  end
 
  def time
    @time = Time.now
    render :update do |page|
      page.insert_html :bottom 'time_div', "#{@time.to_s}<br />"
    end
  end
end

If someone visited /foo, it would show them a link saying “Show time”. The line that makes all the difference is client :time, so ...

  • Without client :time
    • link_to_remote call would generate a javascript Ajax.Request(‘/foo/time’)
    • time would be run on the server
    • render :update block would generate javascript to add the “server-generated” time to the bottom on the time div, and then be send back to the client to be run.
  • With client :time
    • a copy of this controller would be sent to the client when someone visits /foo.
    • link_to_remote call would use Silverlight to call the time action on the client
    • render :update block would execute just as it says, without needing to generate javascript.

The beauty of this is with one line you’ve decided to run a bunch of server-side code on the client, and it just happens for you.

This is better than sliced bread!

The Rails way of doing AJAX is by generating HTML on the sever and sending it back to the client with JavaScript that knows how to insert the HTML into the page. This is an awesome way to do it, but can be pretty heavy-weight if you're schlepping around a lot of HTML. In those cases it doesn't save much “response size” over just sending the whole page back again.

People overcome this by pushing some logic to the client. However, this leads to duplicate their Rails logic in JavaScript, and handle serializing/deserializing their ActiveRecord object by hand. This is just flat-out painful, and by the end of it you realize all this server-side Rails code you wrote is wasted.

This pattern of pushing server-side logic to the client is the approach big sites like Twitter and GMail have taken, and it’s really the best way to make web applications feel more responsive ... it’s the whole RIA thing and why Silverlight is cool. Twitter went through a ton of growing pain getting their app to scale well, and I can bet much of it was attributed to “what should we do on the client, and what should we do on the server” (and what should be cached and what should be stored in a database, but that's a different topic altogether).

I’d like to live in a world where you can write your entire app in Ruby, and not have to throw away a ton of code to get some of it running on the client. That’s what I’m trying to accomplish with this project.

You're right, this is better than slided bread!

:-) Let me know what you think about this, and I'll get some code into your hands soon.

As you can probably tell, this personally hit me hard. We had this problem with Assistment. The tutor just wasn’t scaling, and we decided to port the whole thing to JavaScript, eagerly load data onto the client, etc ... all the things we expected our web framework to do for us. This pissed me off to no end, and Ruby in Silverlight is a way to undo those wrongs and make all this possible.

Update: By the way, I got this example working today! Without "client :time" it works as usual, making an AJAX request when clicking on the "Show time" link. But when you add "client :time", clicking on "Show time" simply runs the code on the client! Awesome!

I'm probably going to put this up on RubyForge ... just not sure whether I should make my own project or stick it in the IronRuby? Regardless, code is coming =)

comments powered by Disqus