Upgrade to Rails 1.1.3 Now
Eric Hodel | Wed, 28 Jun 2006 19:05:35 GMT
DHH writes:
We’ve found and fixed a security issue with routing that could cause excess CPU usage in Rails processes when triggered by certain URLs. We strongly encourage anyone running 1.1.x to upgrade to the latest version. It’s fully backwards compatible and should serve as a small drop-in fix.
While certain URLs cause excess CPU usage, other URLs cause Rails to shut down uncleanly or halt (depending upon deployment environment). You need to upgrade. (It appears that Rails 1.0 is not vulnerable to this DOS, but I haven’t tested.)
While you’re upgrading, check your dispatch.fcgi, it should look like the current dispatch.fcgi. If it doesn’t, you need to upgrade it. There are other DOSs in older versions of dispatch.fcgi.
Supercharged Rails Development
Eric Hodel | Thu, 20 Apr 2006 21:42:22 GMT
Geoff brings us a movie of autotest in action and has this to say:
My development process has recently been supercharged by autotest, a part of the ZenTest package.
[...]
The revolutionary part of this is that it speeds development by helping you develop without needing to open your web browser! I find myself thinking more about the functional issues that need to be solved rather than the placement of an image or the color of a link.
Speeding up Test Runs with fork
Eric Hodel | Sun, 09 Apr 2006 03:47:00 GMT
Loading Rails takes a significant portion of your test run time, especially when you want to run only one test file or one test method. On my Powerbook loading Rails takes between four and six seconds. If you're frequently running unit tests this constant overhead can quickly become annoying.
When using autotest I may have to wait as much as ten seconds (five seconds between scans for changes, four seconds to load rails, one second to run the test) before I know if my changes fixed a problem or not. Ten seconds is past the threshold where I can keep paying attention which makes my mind wander. (A wandering mind is no good for productive work.) Also, those extra four seconds of loading Rails per test start to add up. I may load rails hundreds of times in a day just to run a tiny test.
There's one already existing way to reduce or eliminate that constant overhead of loading Rails. In development mode Rails reloads files to keep things running without restarting Rails on every change. I prefer to have an environment that is guaranteed to be clean when the tests start and reloading files removes this option.
Since I want Rails loaded without any application code I chose to create a process that would load rails then open up a server socket and wait for connections. When a connection comes in the process will fork to make a copy of the environment that can then load the application and run the tests.
A regular test run for just one file runs like this:
$ time ruby test/controllers/route_controller_test.rb Loaded suite test/controllers/route_controller_test Started ...................................................... Finished in 13.192465 seconds. 54 tests, 268 assertions, 0 failures, 0 errors real 0m17.884s user 0m8.147s sys 0m1.424s
The difference between the real time and the Test::Unit run time accounts for Rails and app loading overhead, about five seconds.
I've tentatively named the parent process spawner 'ruby_fork' and the client 'ruby_fork_client', so you start up the parent process:
$ RAILS_ENV='test' ruby_fork -r rubygems -e 'require_gem "rails"' /Users/drbrain/Links/ZT/bin/ruby_fork Running as PID 3570 on 9084
ruby_fork understands -r, -I and -e just like regular ruby so I can just load Rails and none of the rest of my application.
Then I run ruby_fork_client which takes its arguments and passes them across to the child process and then reads from the socket and prints to STDOUT.
$ time ruby_fork_client -r test/controllers/route_controller_test.rb Loaded suite /Users/drbrain/Links/ZT/bin/ruby_fork Started ...................................................... Finished in 12.442556 seconds. 54 tests, 268 assertions, 0 failures, 0 errors real 0m13.947s user 0m0.077s sys 0m0.022s
Now that extra time spent loading Rails is gone and I'm left with application loading and Test::Unit overhead which is miniscule in comparison.
ruby_fork is not Rails specific. The server and client can do anything they like, so this has applications beyond testing Rails (for example, handling incoming mail) or even Rails itself.
I'd like to release ruby_fork and ruby_fork_client as part of ZenTest but I'll be holding it until 3.3.0. Currently ZenTest is almost ready for release and ruby_fork and ruby_fork_client needs to act more like a regular invocation of ruby.
2.5 million
Eric Hodel | Tue, 07 Mar 2006 06:40:00 GMT
On Saturday March 4th the sites of The Robot Co-op handled 2,587,240 requests through Rails. That number includes redirects and error pages but excludes images, CSS and static javascript (we dynamically generate some JS for blog posting).
Memcache-client benchmarks
Eric Hodel | Mon, 06 Mar 2006 22:15:00 GMT
Stefan Kaes writes about using memcached for Ruby on Rails session storage wherein he finds that memcache-client beats out all comers in his session store benchmarks:
memcache-client-1.0.3 provides much better performance: much faster than either the old implementation, pstore or ActiveRecordStore, but also faster than my optimized SQLSessionStore using MysqlSession.
AWESOME
Eric Hodel | Mon, 13 Feb 2006 02:31:00 GMT
Breaking Rails’ functional tests into controller tests and view tests will allow easy auditing between the two types of tests.
But first I need to move all the view assertions out of my functional tests.
DOS Vuln in Rails
Eric Hodel | Tue, 01 Nov 2005 01:09:00 GMT
And I’m not telling you what it is, unless you’re named zenspider.
Rails Functional TestCase
Eric Hodel | Tue, 18 Oct 2005 07:26:00 GMT
Its a shame that Rails doesn’t define its own Test::Unit::TestCase subclasses. I’ve taken that into my own hands. This one puts Test on the front because that’s the Test::Unit way.
require 'test/unit'
def Object.path2class(klassname)
klassname.split('::').inject(Object) { |k,n| k.const_get n }
end
class FunctionalTestCase < Test::Unit::TestCase
def setup
self.class.name =~ /\ATest(.*)\Z/
return unless $1
controller_klass = Object.path2class $1
@controller = controller_klass.new
controller_klass.send(:define_method, :rescue_action) { |e| raise e }
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
@deliveries = []
ActionMailer::Base.deliveries = @deliveries
end
def test_stupid
end
end
Easy model urls for Rails
Eric Hodel | Tue, 18 Oct 2005 07:19:00 GMT
One part url params
class Player < ActiveRecord::Base
def url_params
return { :controller => 'players', :action => 'info', :id => username }
end
end
One part url_for override
class ApplicationController < ActionController::Base
def url_for(options, *params)
if options.include? :model then
options = options.delete(:model).url_params.merge options
end
return super(options, *params)
end
end
[Simplified due to some insight from zenspider]
Then just add :model => AR_object to anything that accepts url params:
<ul>
<% @players.each do |player| -%>
<li><%= link_to player.username, :model => player %>
<% end -%>
</ul>
And ba-bam!
<ul>
<li><a href="/players/info/herbert">herbert</a>
<li><a href="/players/info/joseph">joseph</a>
</ul>

Articles