Hey Rails, nice Rack!
Posted by ezmobius Fri, 25 Apr 2008 00:34:00 GMT
So i’ve spent this week hacking on Rails, specifically going spelunking in ActionPack and porting Merb’s rack machinery to rails. I figure that merb is a very nice experimentation ground and decided it was time to give some love back to the framework that inspired merb.
While still not complete, I have made significant headway on racking up rails in my github fork of Rails. I’ve added rack adapters for mongrel, eventedmongrel, thin, ebb and webrick. All of this is controlled via ./script/rackup in a rails app. So to start a cluster of 5 thin servers you would run this command:
./script/rackup -a thin -c 5 -e production
I do have to say that parts of ActionPack haven’t been touched in a long time and had accumulated some cruft, with the rails rack adapter that thin and ebb use there was a dogpile of wrappers going on. A web request was wrapped in many layers like this(the → means ‘wrapped in’)
raw request -> rack env -> Rack::Request -> CGIWrapper -> CgiRequest
That was far too many wrappers, it also turned out that some of these wrapper were making duplicates of all the CGI headers, meaning quit a bit of wasted memory on every request. I’ve slimmed it down to this now:
raw request -> rack env -> ActionController::RackRequest
With no more duplication of CGI headers, win!
I’ve also changed the giant mutex lock to be much smaller, it used to lock around the dispatcher callbacks, route recognition, controller instantiation, filters and action dispatch. Now it only locks around filters and action dispatch, Dispatcher callbacks, route recognition and controller instantiation all happen outside of the lock. This makes for a nice little speed boost with standard mongrel under concurrent load.
Of course this doesn’t work so hot in development mode when you have concurrent requests, it falls apart due to route set reloading and class reloading done in dev mode. But if you are just using your browser to test the app in dev mode you won;t ever notice since you won;t be making concurrent requests. In production mode the route recognition appears to be thread safe, more extensive testing and stressing will be needed to be 100% certain though.
All in all I feel like these are some big wins for Rails. And I’m not done yet, I plan on beating up ActionPack quite a bit more until it submits ;)