Rails 2.2 RC2: Last stop before final

Posted 4 days back at Riding Rails - home

Rails 2.2 has been baking for long enough now. This is the last taste before the goodies are served. So please install and check it out. See if you can find any regressions or bugs in any of the new stuff, so we can have it all delicious by the time we ring the dinner bell (ok, ok, I’ll put down the food metaphor now).

This release also conciedes with the fact that we’ve branches 2-2-stable, which means that master is now actually targeting Rails 2.3/3.0. There’s also a tag available for this RC as v2.2.1.

If you missed RC1, have a look at the Rails 2.2 release notes to see the major additions. You can see what’s new since RC1 in these two This Week in Edge Rails.

To install, you must first have RubyGems 1.3.1:
gem update --system.

Then you can:
gem install rails -s http://gems.rubyonrails.org

Enjoy!

Ruby Best Practices: The Book and Interview with Gregory Brown

Posted 4 days back at Ruby Inside

ruby-best-practices.gifBack in March, Ruby developer Gregory Brown raised the idea of receiving donations so he could work on open source Ruby projects full-time. It went well, and out of this project came Prawn, a pure Ruby PDF generation library. Not one to rest on his laurels, Gregory's now working on a book for O'Reilly called Ruby Best Practices, billed as "for programmers who want to use Ruby the way Rubyists do." The book will cover how to design "beautiful" APIs and DSLs, along with lots of other general topics that will make your code more expressive and make you a better Ruby developer into the bargain.

The book is not due for final release until August 2009, but thanks to O'Reilly's "Rough Cuts" program, the first three chapters (Driving Code Through Tests, Designing Beautiful APIs, and Text Processing and File Management) are already available. Online-only access is $17.99 and you'll get the latest version as it becomes available. Print-only and Print + Online bundles are also available.

Gregory gave me a copy of the first three chapters to look over, and they're well crafted. This definitely isn't a reference book, a "cook book" or any sort of book you merely "dip" into. It's designed to be read by the chapter. The first chapter, Driving Code Through Tests, for example, takes you on a journey through the world of testing in Rubyland from motivation through to best practices - it's a full introduction to a single topic.

The Interview

I decided to ask Gregory a few questions to get more background on the book, as well as an update on his Ruby Mendicant project:

What was the inspiration for writing Ruby Best Practices?

Right now, it's entirely possible for one to learn enough Ruby to get by without ever understanding why people love the language. I think one reason is that our books have disproportionately emphasized on solving particular problems, via some recipe or pattern. We've also got a ton of introductions to the language, some better than others, but these books don't dive into code that looks or feels real. Our reference books are great (at least IMO), but they're only telling you what sharp tools are in the shed, not how to use them.

Ruby Best Practices is a book about why Rubyists tend to write Ruby the way they do. So this book looks at a lot of real code, most of it from open source projects, and tries to make it approachable to any reader who's got a reference book handy, so long as their willing to engage their brain a bit. I'm hoping that people will have fun learning a bit more about the 'why' behind a lot of the design decisions we face when writing code.

Does the rapid pace of change in the Ruby community makes writing a book like this more difficult?

I think change is generally good, and that folks who wish to live on the edge must be willing to pay the price. There's nothing wrong with using older versions of software if you're not ready to make the jump to the new hotness of the week.

However, I want this book to be current when it prints, and I also want to help encourage people to move forward, so I've been writing against Ruby 1.9.1 only. Because the only place 1.8 is mentioned is in my chapter on how to write backwards-compatible code, I don't have the pain that most people do with updating their notes constantly about changes in 1.9 vs 1.8. I just need to make sure my code keeps running properly on 1.9.1 until the time the book is released. There are hiccups from time to time, but I've definitely been in less pain than anyone who's trying to write a reference book right now.

What sort of developer should be buying this book right now?

I think that any developer who has worked through some introductory Ruby material and has a reference book handy can learn something from RBP. I've got a couple internal reviewers who are in exactly that position, so they help keep that target audience in range.

However, in terms of the Rough Cuts release, what I need most is folks who are fairly strong in idiomatic Ruby to pick up a copy and help correct me where I am wrong. I put together a great team of internal reviewers who check every chapter before it becomes public, but more eyes will surely help shape the book before it hits the shelves.

I definitely want the book to have the kind of authority that comes from extensive peer review instead of having people trust it based on name recognition. If people provide feedback through Rough Cuts, I think it'll be easier to accomplish that goal.

How is the Ruby Mendicant project going?

The Ruby Mendicant project officially ended on September 30th, two weeks after the scheduled end-date. However, I'm still actively working on Prawn and will continue to move things forward over the coming months. I came up a little short of the hours I initially pledged, but accomplished most of the goals I had in mind. We're getting closer and closer to providing a replacement for PDF::Writer, and many users have already made the jump.

I gave a talk on Ruby Mendicant / Prawn at RubyConf, and it's probably the best summary I've done so far, which people could check out once Confreaks gets the video online. I also plan to write a post-mortem about the whole experience but haven't found time just yet. I'll link it on that talk page once it's available.

Myth #3: Rails forces you to use Prototype

Posted 4 days back at Loud Thinking

There are lots of great JavaScript libraries out there. Prototype is one of the best and it ships along Rails as the default choice for adding Ajax to your application.

Does that mean you have to use Prototype if you prefer something else? Absolutely not! Does it mean that it's hard to use something else than Prototype? No way!

It's incredibly easy to use another JavaScript library with Rails. Let's say that you wanted to use jQuery. All you would have to do is add the jQuery libraries to public/javascripts and include something like this to the <head> in your layout to include the core and ui parts:

<%= javascript_include_tag "jquery", "jquery-ui" %>

Then say you have a form like the following that you want to Ajax:

<% form_for(Comment.new) do |form| %>

<%= form.text_area :body %>
<%= form.submit %>
<% end %>

By virtue of the conventions, this form will have an id of new_comment, which you can decorate with an event in, say, application.js with jQuery like this:


$(document).ready(function() {
$("#new_comment").submit(function() {
$.post($(this).attr('action') + '.js',
$(this).serializeArray(), null, 'script');

return false;
});
});

This will make the form submit to /comments.js via Ajax, which you can then catch in the PostsController with a simple format alongside the HTML response:

def create

@comment = Post.create(params[:comment])

respond_to do |format|
format.html { redirect_to(@comment) }
format.js
end
end

The empty format.js simply tells the controller that there's a template ready to be rendered when a JavaScript request is incoming. This template would live in comments/create.js.erb and could look something like:

$('#comments').append(

'<%= escape_javascript(render(:partial => @comment)) %>');
$('#new_comment textarea').val("");
$('#<%= dom_id(@comment) %>').effect("highlight");

This will append the newly created @comment model to a dom element with the id of comments by rendering the comments/comment partial. Then it clears the form and finally highlights the new comment as identified by dom id "comment_X".

That's pretty much it. You're now using Rails to create an Ajax application with jQuery and you even get to tell all the cool kids that your application is unobtrusive. That'll impress them for sure :).

Rails loves all Ajax, not just the Prototype kind
This is all to say that the base infrastructure of Rails is just as happy to return JavaScript made from any other package than Prototype. It's all just a mime type anyway.

Now if you don't want to put on the unobtrusive bandana and instead would like a little more help to define your JavaScript inline, like with remote_form_for and friends, you can have a look at something like jRails, which mimics the Prototype helpers for jQuery. There's apparently a similar project underway for MooTools too.

So by all means use the JavaScript library that suits your style, but please stop crying that Rails happens to include a default choice. That's what Rails is. A collection of default choices. You accept the ones where you don't care about the answer or simply just agree, you swap out the ones where you differ.

Update: Ryan Bates has created a screencast that shows you how to do the steps I outlined above and more.

See the Rails Myths index for more myths about Rails.

Myth #3: Rails forces you to use Prototype

Posted 4 days back at Loud Thinking

There are lots of great JavaScript libraries out there. Prototype is one of the best and it ships along Rails as the default choice for adding Ajax to your application. Does that mean you have to use Prototype if you prefer something else? Absolutely not! Does it mean that it's hard to use something else than Prototype? No way!

It's incredibly easy to use another JavaScript library with Rails. Let's say that you wanted to use jQuery. All you would have to do is add the jQuery libraries to public/javascripts and include something like this to the <head> in your layout to include the core and ui parts:

<%= javascript_include_tag "jquery", "jquery-ui" %>

Then say you have a form like the following that you want to Ajax:


<% form_for(Comment.new) do |p| %>
<%= p.text_area :body %>
<%= p.submit %>
<% end %>

By virtue of the conventions, this form will have an id of new_comment, which you can decorate with an event in, say, application.js with jQuery like this:


$(document).ready(function() {
$("#new_comment").submit(function() {
$.post($(this).attr('action') + '.js',
$(this).serializeArray(), null, 'script');

return false;
});
});

This will make the form submit to /comments.js via Ajax, which you can then catch in the PostsController with a simple format alongside HTML and XML responses:


def create
@comment = Post.create(params[:comment])

respond_to do |format|
format.html { redirect_to(@comment) }
format.xml { render :xml => @comment, :status => :created, :location => @comment }
format.js
end
end

The empty format.js simply tells the controller that there's a template ready to be rendered when a JavaScript request is incoming. This template would live in comments/create.js.erb and could look something like:


$('#comments').append('<%= escape_javascript(render(:partial => @comment)) %>');
$('#new_comment textarea').val("");
$('#<%= dom_id(@comment) %>').effect("highlight");

This will append the newly created @comment model to a dom element with the id of comments by rendering the comments/comment partial. Then it clears the form and finally highlights the new comment as identified by dom id "comment_X".

That's pretty much it. You're now using Rails to create an Ajax application with jQuery and you even get to tell all the cool kids that your application is unobtrusive. That'll impress them for sure :).

This is all to say that the base infrastructure of Rails is just as happy to return JavaScript made from any other package than Prototype. It's all just a mime type anyway.

Now if you don't want to put on the unobtrusive bandanna and instead would like a little more help to define your JavaScript inline, like with remote_form_for and friends, you can have a look at something like jRails, which mimics the Prototype helpers for jQuery. There's apparently a similar project underway for MooTools too.

So by all means use the JavaScript library that suits your style, but please stop crying that Rails happens to include a default choice. That's what Rails is. A collection of default choices. You accept the ones where you don't care about the answer or simply just agree, you swap out the ones where you differ.

Sinatra for IRC

Posted 4 days back at RailsTips.org - Home

In which I extol the virtues of Isaac for working with IRC in Ruby and at the same time beg library authors to rethink their APIs.

My favorite Campfire feature is the history. I love that it persists between Campfire sessions. On the opposite side of the spectrum, I hate that IRC doesn’t. I decided it would be nice to have a bot that sits in the room and stores all the chatter to the database. Once that was working, it would be handy to have a simple web front end that allowed searching and viewing by day. I have seen sites out there that do that but like any programmer decided to make something for myself.

Finding Some Code

First up, I needed to find a good IRC library for Ruby. I did research for about 30 minutes and found a ton of libraries on GitHub: Net/IRC, on_irc, irc4r, irkr, rbot, minibot, kirby and autumn. I even came across the code that runs rails.loglibrary.com, which is kind of what I want to do but not quite. Each library did things a bit differently and they all had their strengths and weaknesses, but one thing stood out: they almost all required that I was familiar with IRC protocols and terminologies.

The Solution

If I was getting paid to do this, I would want to know inside and out how things work. Because this is a side project, I just wanted to get up and running quickly. At that moment, I remembered SearchParty (which incidentally runs on Sinatra) and headed over there to search for irc. Right at the top of my delicious items was Isaac, which I had totally forgotten about.

“You want to create an IRC bot quickly? Then Isaac is you.”

Yes, I want to create an IRC bot quickly. That is exactly what I want to do.

“Be aware…a large portion of the IRC standard has not been implemented, simply because I haven’t needed it yet.”

I don’t care if the entire spec is implemented. All I care about is whether or not the stuff I want is implemented and what the API is in Ruby to do that stuff.

Installation of Isaac

For whatever reason, at this time Isaac does not seem to be on RubyForge and the gem has evidently failed to build on GitHub, so I had to build the gem manually (which is easy but not obvious).

git clone git://github.com/ichverstehe/isaac.git
cd isaac
gem build isaac.gemspec
sudo gem install isaac-0.0.2.gem

That did the trick for me and should work fine for you as well.

The Code

A few minutes later, I had the following snippet of code running which allowed my bot to login to an IRC room and listen to all the chatter. Wow. Awesome.


require 'rubygems'
require 'isaac'

config do |c|
  c.nick    = "fantasticalbot" 
  c.server  = "irc.freenode.net" 
  c.port    = 6667
end

on :connect do
  join "#fantasticalroom" 
end

on :channel, /.*/ do
  msg channel, "Got your message #{nick} (#{match[0]})" 
end

If you have used Sinatra, you can immediately see the similarities. You can even define helpers in the same way that you would with Sinatra. Now this doesn’t do everything I mentioned that I want to do, but it was a nice start. All that is left is to drop in ActiveRecord or DataMapper or implement some kind of a web hook to an app and I am good to go.

Conclusion

There are two points to this article. The first is that Isaac is really cool if you want to dabble with IRC from Ruby. The second point, and probably more important, is when you create a library, think about the API that other programmers will use more than you think about the spec you are implementing. I suspect few people out there want to learn every spec that they work with. Most people are probably like me and have a simple need and want a simple solution.

This is one of the reasons HTTParty was created and why I am now working on IMAParty. Spec is important, but every “to the spec” library needs a simplistic DSL on top that makes them easy to use for the 80% of people that only need 20% of the features.

Sinatra for IRC

Posted 4 days back at RailsTips.org - Home

In which I extol the virtues of Isaac for working with IRC in Ruby and at the same time beg library authors to rethink their APIs.

My favorite Campfire feature is the history. I love that it persists between Campfire sessions. On the opposite side of the spectrum, I hate that IRC doesn’t. I decided it would be nice to have a bot that sits in the room and stores all the chatter to the database. Once that was working, it would be handy to have a simple web front end that allowed searching and viewing by day. I have seen sites out there that do that but like any programmer decided to make something for myself.

Finding Some Code

First up, I needed to find a good IRC library for Ruby. I did research for about 30 minutes and found a ton of libraries on GitHub: Net/IRC, on_irc, irc4r, irkr, rbot, minibot, kirby and autumn. I even came across the code that runs rails.loglibrary.com, which is kind of what I want to do but not quite. Each library did things a bit differently and they all had their strengths and weaknesses, but one thing stood out: they almost all required that I was familiar with IRC protocols and terminologies.

The Solution

If I was getting paid to do this, I would want to know inside and out how things work. Because this is a side project, I just wanted to get up and running quickly. At that moment, I remembered SearchParty (which incidentally runs on Sinatra) and headed over there to search for irc. Right at the top of my delicious items was Isaac, which I had totally forgotten about.

“You want to create an IRC bot quickly? Then Isaac is you.”

Yes, I want to create an IRC bot quickly. That is exactly what I want to do.

“Be aware…a large portion of the IRC standard has not been implemented, simply because I haven???t needed it yet.”

I don’t care if the entire spec is implemented. All I care about is whether or not the stuff I want is implemented and what the API is in Ruby to do that stuff.

Installation of Isaac

For whatever reason, at this time Isaac does not seem to be on RubyForge and the gem has evidently failed to build on GitHub, so I had to build the gem manually (which is easy but not obvious).

git clone git://github.com/ichverstehe/isaac.git
cd isaac
gem build isaac.gemspec
sudo gem install isaac-0.0.2.gem

That did the trick for me and should work fine for you as well.

The Code

A few minutes later, I had the following snippet of code running which allowed my bot to login to an IRC room and listen to all the chatter. Wow. Awesome.


require 'rubygems'
require 'isaac'

config do |c|
  c.nick    = "fantasticalbot" 
  c.server  = "irc.freenode.net" 
  c.port    = 6667
end

on :connect do
  join "#fantasticalroom" 
end

on :channel, /.*/ do
  msg channel, "Got your message #{nick} (#{match[0]})" 
end

If you have used Sinatra, you can immediately see the similarities. You can even define helpers in the same way that you would with Sinatra. Now this doesn’t do everything I mentioned that I want to do, but it was a nice start. All that is left is to drop in ActiveRecord or DataMapper or implement some kind of a web hook to an app and I am good to go.

Conclusion

There are two points to this article. The first is that Isaac is really cool if you want to dabble with IRC from Ruby. The second point, and probably more important, is when you create a library, think about the API that other programmers will use more than you think about the spec you are implementing. I suspect few people out there want to learn every spec that they work with. Most people are probably like me and have a simple need and want a simple solution.

This is one of the reasons HTTParty was created and why I am now working on IMAParty. Spec is important, but every “to the spec” library needs a simplistic DSL on top that makes them easy to use for the 80% of people that only need 20% of the features.

This Week in Edge Rails

Posted 4 days back at Riding Rails - home

The important news in edge Rails this week is the imminent release of Rails 2.2.1 – otherwise known as Rails 2.2 RC2. Getting ready for this release did lead to some significant changes in the Rails codebase.

First, it’s very likely that you’ll need to upgrade rubygems to run RC2: the required version of rubygems is now 1.3.1, which was just released yesterday. This dependency is part of the continued work to make vendored gems useful and stable. You may find that updating rubygems is less than smooth, depending on your current version; check out this article if you have any trouble. commit

The Rails routing engine has seen some serious work over the past week as well. For starters, Jeremy Kemper committed several fixes to the core routing engine that cut down on object creation and RegExp creation, trimming memory use. commit commit There are also new :only and :except options for map.resources, which can help cut down memory use if you have a lot of resource routes – see these articles for details (though there have been some tweaks in the way nested limited routes work after those were written). commit commit commit

The new ActiveRecord connection pooling code has seen some tuning as well, making it more efficient in development model and avoiding some issues with the Oracle adapter. commit

Polymorphic URLs now behave more intuitively if one of their parameters is nil. For example, a call to polymorphic_path([@project, @filter, @issue]) with a nil filter now returns project_issue_url instead of a NoMethodError. commit

The request forgery protection feature in Rails has been tightened up so that it only applies to HTML-formatted content requests. There is substantial discussion on the Lighthouse ticket that led to this change, but the bottom line is that the old implementation had some bugs, notably making destroy actions inaccessible via XML. Other types of requests are protected by other means – for instance, the same origin policy on AJAX requests substitutes for request forgery protection there. commit

Double Shot #332

Posted 4 days back at A Fresh Cup


Been having great fun coming up to speed with shoulda the last few days. I think it’s finally starting to make sense to me, though surely there are best practices I’m still missing.

  • Spandex MemCache Store - An enhanced version of the default Rails memcache bits.
  • RubyGems 1.3.1 - New minor release. So far it hasn’t caused any new issues for my major applications.
  • Concurrency is a Myth in Ruby - Well, yes, although JRuby does present a different situation.
  • Shoulda Testing Cheat Sheet - A useful thing to have around when you’re learning.
  • ActiveRitalin - A Rails plugin built on the premise that “Rails find_by_sql is the devil.”
  • The Rails Myths - DHH tries to set the record straight. Good luck with that.
  •       

    Comparing Amazon's EC2, Google's App Engine and Microsoft's Azure

    Posted 4 days back at InfoQ Personalized Feed for unregistered user - Register to upgrade!

    The weather forecast changed when Microsoft entered the clouds with the Azure platform during PDC 2008. It would be interesting to compare the three major offerings existing on the market today, Amazon's, Google's and Microsoft's, and at the first glance it seems that they are not really competing against each other. By Abel Avram

    Ruby Networking on Steroids

    Posted 5 days back at oldmoe

    Ruby provides several socket classes for various connection protocols. Those classes are arranged in a strange and a convoluted hierarchy.
    This ASCII diagram explains this hierarchy


    IO
    |
    BasicSocket
    |
    |-- IPSocket
    | |
    | |-- TCPSocekt
    | | |
    | | |-- TCPServer
    | | |
    | | |-- SocksSocket
    | |
    | |-- UDPSocket
    |
    |-- Socket
    |
    |-- UNIXSocket
    |
    UNIXServer

    The BasicSocket class provides some common methods but you cannot instantiate it. You have to use one of the sub classes. We have three branches coming out from BasicSocket. One that implements the IP (and descendant) protocls the other implements the UNIX domain sockets protocol. A third branch provides a generic wrapper over FreeBSD sockets. The first problem with this branching strategy is that while the Socket class can be used as a parent class to both UNIXSocket and IPSocket classes the implementer chose to create a separate path for each of them. This results in that there exists lots of code duplication in the implementation that makes maintaining those classes a lot harder than it should be.

    A prime example for this is the addition of non blocking features lately to the I/O and socket classes. Only the Socket class was lucky enough to get an accept_nonblocking method. The other classes sadly didn't get it. It is very important to be able to initiate network connections in a non blocking manner if you are using an evented framework (like NeverBlock for example).

    What makes the problem worse is that major Ruby network libraries overlook the Socket class and use TCPSocket or UNIXSocket. Net/HTTP for example uses TCPSocket. Since NeverBlock tries to work in harmony with most Ruby libraries it attempts to make up for this inconsistency by altering the default heirarechy of socket classes. Ruby allows you to un-define constants in an object. We remove the TCPSocket and UNIXSocket classes and redefine them by inheriting from Socket and defining some methods to make up for any lost functionality.

    After modifying the Socket classes NeverBlock support was integrated. This was done by rewriting the connect, read and write methods so that they would detect the presence of a NeverBlock fiber and operate in an aysnchronous way accordingly. If you use the new socket classes in a non NeverBlock context or in NeverBlock's blocking mode they will resort to the old blocking implementation.

    So Here is an example. First we will create a server using EventMachine that takes 1 second to process each request.

    server.rb

    require 'eventmachine'

    class Server < EM::Connection
    # handle requests here
    def receive_data data
    # set the respnonse to be sent after 1 second
    EM.add_timer(1) do
    send_data "HTTP/1.1 200 OK\r\n\r\ndone"
    close_connection_after_writing
    end
    end
    end

    EM.run do
    EM.start_server('0.0.0.0',8080, Server)
    end


    Second we will create a client that will issue requests to the server

    client.rb

    require 'neverblock'
    require 'net/http'
    EM.run do
    @pool = NB::FiberPool.new(20)
    20.times do
    @pool.spawn do
    url = "http://localhost:8080"
    res = Net::HTTP.start(url.host, url.port) { |http| http.get('/') }
    end
    end
    end

    Issuing 20 GET requests in NeverBlock fibers causes them to run concurrently. Even while our server process a request in one complete second, they all return after approximately 1 second.

    Here is a blocking version

    blocking_client.rb

    require 'net/http'
    20.times do
    url = "http://localhost:8080"
    res = Net::HTTP.start(url.host, url.port) { |http| http.get('/') }
    end


    The blocking client finishes after around 20 seconds.

    Here's a teaser graph



    The really good thing is that we used the Net/HTTP library transparently. Any Ruby library that relies on Ruby sockets will benefit from NeverBlock and gain the ability to run in a concurrent manner.

    What does that mean?

    Originally, NeverBlock only supported concurrent database access for PostgreSQL and MySQL. While this was good and all, databases usually were the bottlenecks of most applications. Unless you have something like a database cluster which can truly absorb any load. This was a shame, since NeverBlock is meant for high levels of concurrency that are only available with massively scalable back ends. With this new development, however, we are now one step closer to tapping into this realm of high performance and scalable web applications. Read on.

    Enter AWS and the cloud

    Amazon Web Services provide an example of a massively scalable backend that is accessible via HTTP. Services like S3, SimpleDB and SQS are all a URL away. Such services have a higher latency than your nearby database server but they more than make up for that by being able to absorb all the requests you through at them. Most of the Ruby libraries for accessing AWS rely on Net/HTTP in some way or another. This means we get NeverBlock support for those libraries. Now this is big news for those Ruby applications (including Rails ones) that rely on an AWS or a similar backend. For those types of apps, forget about a 10 or 20 fibers pool. We are talking a 1000 fibers pool here. Even higher numbers could be possible (once a nasty file descriptor bug in Ruby 1.9 is fixed).

    Why Not Threads?

    I have been claiming that Ruby fibers are faster than Ruby threads[1]. I have seen that in my tests but those were usually limited to testing a single performance metric. So I decided to simulate a very scalable back end and see which approach offers more scalability. For testing purposes I created two client applications. One is threaded and the other is based on NeverBlock. In the NeverBlock version I did not use the fiber pool though, I was creating a new fiber per operation to mimic the threaded app behavior. The simulated scalable back end consisted of an EventMachine based server that waits for a certain time before responding with 200 OK. The delay time is to simulate back end processing and network latencies. I testing using 0, 10, 50, 100 and 500 ms as delay values. Another client application was written that worked in the normal blocking mode for comparison.

    The clients were tested using Ruby 1.8.6 and 1.9.1. The only exception was the NeverBlock client which was only tested with 1.9.1. This is due to the fact that the current fiber implementation for Ruby 1.8.x is based on threads so it will only reflect a threaded implementation performance. Ruby1.8 was introduced because I noticed problems with the Ruby 1.9 threading implementation regarding scalability and performance so I added Ruby1.8 to the mix which proved to have a (sometimes) faster and more scalable threading implementation.

    The application will attempt to issue 1000 requests to the back end server and will try to do so in a concurrent fashion (except for the blocking version of course)

    Here are the results



    And the results in ASCII format (numbers in cells are requests/sec)

    Server Delay 0ms 10ms 50ms 100ms 500ms

    Ruby1.8 Blocking 2000 19 16 10 2

    Ruby1.9 Blocking 2400 19 17 10 2

    Ruby1.8 Threaded 1050 800 670 536 415

    Ruby1.9 Threaded 618 470 451 441 395

    Ruby1.9 NeverBlock 2360 1997 1837 1656 1031

    Let's try to explain the results. For a server that has no delay whatsoever (a utopian assumption) we see that the blocking servers offer the greatest performance. Ruby 1.9 in blocking mode comes first mainly due to the fact that Ruby1.9 is faster than Ruby1.8 and also comes with a faster Net/HTTP library[1]. Why is blocking faster? Simply because the evented server is processing the requests serially and the latency is minimal. The request processing send a response and returns immediately so the server does not get a chance to process requests concurrently. This is the fastest that you can drive your processor.

    The NeverBlock implementation comes as a very close second to the fastest client which shows that the overhead of using fibers is not that much. Actually we are cheating a bit here, because we make up for the overhead by sending the requests concurrently, and while the server is still processing the serially we are able to process the fiber pause and resume while the server is working.

    Needless to say, NeverBlock is much ahead of the threaded clients (either 1.8 or 1.9) when working with the zero latency server. We also see that 1.8 threads are considerably faster than 1.9's.

    When we start adding a simulated delay to the server we see that the blocking clients fall dramatically from the first position to the last. They become too slow that they are really not suitable for use in that setting any more. Please note that the results for the 500ms delay are extrapolations. I was to annoyed by the idea of waiting 500 seconds for a test to run, twice!

    On the other hand, threaded and NeverBlock implementations are much less affected even though they lose ground as we increase the delay. NeverBlock maintains its lead though over threaded clients. It is generally 2.5X faster.

    Here is a graph of the NeverBlock advantage over the fastest threaded client



    And in ASCII format

    Server Delay 0ms 10ms 50ms 100ms 500ms

    NeverBlock Advantage 124.76% 149.63% 174.18% 208.96% 148.43%

    Aside from the NeverBlock advantage the numbers themselves are very impressive. A single process can achieve ~1000 operations per second given that we have half a second processing and network latency. In a mutli process setup we should be able to achieve a lot more than that. For example, forking another NeverBlock client on my dual core notebook which hosts the client and the server apps adds a 50% performance gain.

    Conclusion

    NeverBlock really shines when the back end is highly scalable. The only problem I met was a Ruby1.9 bug that crashed the client when the file descriptors exceeded 1024. I hope this could be fixed as it will enable us to extract more performance from each process. Expect the socket support to be officially added to NeverBlock soon.

    RubyGems 1.3.1

    Posted 5 days back at Segment7

    NOTE: RubyGems 1.1 and 1.2 have problems upgrading when there is no rubygems-update installed. You will need to follow the second set of update instructions if you see “Nothing to update”.

    Release 1.3.1 fixes some bugs.

    Bugs fixed:

    • Disregard ownership of ~ under Windows while creating ~/.gem. Fixes issues related to no uid support under Windows.
    • Fix requires for Gem::inflate, Gem::deflate, etc.
    • Make Gem.dir respect :gemhome value from config. (Note: this feature may be removed since it is hard to implement on 1.9.)
    • Kernel methods are now private. Patch #20801 by James M. Lawrence.
    • Gem::location_of_caller now behaves on Windows. Patch by Daniel Berger.
    • Silence PATH warning.

    Deprecation Notices:

    • Gem::manage_gems will be removed on or after March 2009.

    For a full list of changes to RubyGems and the contributor for each change, see the ChangeLog file.

    Special thanks to Chad Wooley for backwards compatibility testing and Luis Lavena for continuing windows support.

    How can I get RubyGems?

    NOTE: If you have installed RubyGems using a package system you may want to install a new RubyGems through the same packaging system.

    If you have a recent version of RubyGems (0.8.5 or later), then all you need to do is:

    $ gem update --system   (you might need to be admin/root)

    NOTE: RubyGems 1.1 and 1.2 have problems upgrading when there is no rubygems-update installed. You will need to follow the second set of update instructions if you see “Nothing to update”.

    NOTE: You may have to run the command twice if you have any previosly installed rubygems-update gems.

    If you have an older version of RubyGems installed, then you can still do it in two steps:

    $ gem install rubygems-update  (again, might need to be admin/root)
    $ update_rubygems              (... here too)

    If you don’t have any gems install, there is still the pre-gem approach to getting software … doing it manually:

    To File Bugs

    The RubyGems bug tracker can be found on RubyForge at: http://rubyforge.org/tracker/?func=add&group_id=126&atid=575

    When filing a bug, `gem env` output will be helpful in diagnosing the issue.

    If you find a bug where RubyGems crashes, please provide debug output. You can do that with `gem—debug the_command`.

    Keep those gems coming!

    —Jim & Chad & Eric (for the RubyGems team)

    Speaking at ChicagoRuby this Saturday

    Posted 5 days back at Softies on Rails - Home

    Sorry for the late notice – I was having too much fun at RubyConf last week – but I’ll be speaking at the upcoming ChicagoRuby meeting this Saturday. If you’re in the neighborhood, come join us!

    ChicagoRuby is headed up by Ray Hightower, the same guy who made Windy City Rails a reality. You can let us know you’re coming by using this Meetup.com link.

    See you there!

    Speaking at ChicagoRuby this Saturday

    Posted 5 days back at Softies on Rails - Home

    Sorry for the late notice – I was having too much fun at RubyConf last week – but I’ll be speaking at the upcoming ChicagoRuby meeting this Saturday. If you’re in the neighborhood, come join us!

    ChicagoRuby is headed up by Ray Hightower, the same guy who made Windy City Rails a reality. You can let us know you’re coming by using this Meetup.com link.

    See you there!

    Physical vs Logical Modeling in Rails

    Posted 5 days back at Scaling Ruby on Rails with Dan Chak


    I gave a talk on Tuesday at the Boston Ruby User’s Group meeting. The talk was quite exciting, with about 60 people split rather evenly between skeptics and converts to my message. Although they are fairly sparse for consumption without having first heard the talk, the slides are attached. As I understand more and more of the initial objections folks have to splitting up domain and data modeling this way, I’ll be working toward a more comprehensive argument and set of examples. Yes, ideally for the next edition of my book. Here’s the
    PDF.

          

    Physical vs Logical Modeling in Rails

    Posted 5 days back at Scaling Ruby on Rails with Dan Chak


    I gave a talk on Tuesday at the Boston Ruby User’s Group meeting. The talk was quite exciting, with about 60 people split rather evenly between skeptics and converts to my message. Although they are fairly sparse for consumption without having first heard the talk, the slides are attached. As I understand more and more of the initial objections folks have to splitting up domain and data modeling this way, I’ll be working toward a more comprehensive argument and set of examples. Yes, ideally for the next edition of my book. Here’s the
    PDF.

          


    1 ... 4 5 6 7 8 ... 572