Ruby off Rails Rack, Sinatra and Sequel Jiang Wu 2009.3.14
Outline Rack Sinatra Sequel Ruby off Rails Rails Metal: A way of fusion
rack http://rack.rubyforge.net/ Rack aims to provide a minimal API for connecting web servers and web frameworks.
Rack SPEC {"HTTP_USER_AGENT"=>"curl/7.12.2 ...", "REQUEST_URI"=>"http://ruby-lang.org/", "QUERY_STRING"=>"", "HTTP_ACCEPT"=>"*/*", "REQUEST_METHOD"=>"GET", "rack.input" => '...',  ... } call(env) [status, headers, body] to_i each each [String,String] String yields yields
Rack middleware: process RESP RESP RESP Rack Middleware 1 Rack Middleware 3 Rack Middleware 2
A rack middleware can do: Do nothing (usually after a condition judgment) Response directly Alter environment variables Alter response(body, headers and status code)
Write your own rack middleware nothing.ru middleware do nothing calc_time.ru add response time to body method_override.ru alter HTTP method
sinatra http://www.sinatrarb.com/
sinatra program: infinity.rb 1 require 'rubygems' 2 require 'sinatra'   3    4 use Rack::CommonLogger   5 use Rack::ShowExceptions   6    7 get '/' do   8   "Hello, Sinatra"   9 end 10  11 get '/version' do 12   "infinity 0.1" 13 end 14  15 get '/version/last' do 16   "infinity beta 0.13" 17 end
sequel The Database Toolkit for Ruby sequel postgres://localhost/blog Your database is stored in DB...  >> DB.tables => [:blogs, :tags] >> require 'logger' >> DB.logger = Logger.new(STDOUT) >> DB[:tags].filter(:count > 100).order( :name.desc).limit(5).all  INFO -- : SELECT * FROM &quot;tags&quot; WHERE (&quot;count&quot; > 150) ORDER BY &quot;name&quot; DESC LIMIT 5 >> class Tag < Sequel::Model;end >> Tag.filter(:count > 150).order(:name.desc).limit(5).all
sinatra + sequel: a simple note ruby notes.rb Just  ONE  file to run!
Ruby off Rails jquery  vs.   prototype.js jquery UI  vs.  script.aculo.us extlib  vs.   ActiveSupport sequel  vs.   ActiveRecord sinatra  vs.   ActionPack pony  vs.   ActionMailer rest-client  vs.  ActiveResource
Off Rails if you ... Hate the namespace pollution Prototype.js ActiveSupport ActiveRecord pollutes collection Want to use a dispatcher based on URL Hate the constraints Constraint of program structure Constraint of table structure Constraint of URL structure Want to speed up Speed up upload Speed up performance Speed up test performance
On Rails if you ... Need mature plug-ins Need write-through cache(with support from Cache-money) Need existing view helpers Need help from community
Rails metal: new in 2.3 If you have a Rails application that has service end points that need to be  really, really   fast. So fast  that the few milliseconds that a trip through the Rails router and Action Controller path is too much. For this scenario, we’ve built a thin wrapper around the generic  Rack middleware  and given it a place in the hierarchy along with the name “ Metal ” . Introducing Rails Metal   —— DHH
Rails Metal: the code “Hello World” Metal: class Poller < Rails::Rack::Metal def call(env) if env[&quot;PATH_INFO&quot;] =~ /^\/poller/ [200, {&quot;Content-Type&quot; => &quot;text/html&quot;}, &quot;Hello, World!&quot;] else [404, {&quot;Content-Type&quot; => &quot;text/html&quot;}, &quot;Not Found&quot;] end end end “ Hello World” controller: class OldPollerController < ApplicationController def poller render :text => &quot;Hello World!&quot; end end
Rails Metal and sinatra 1 require 'sinatra/base' 2  3 class Hello < Sinatra::Base 4  # all options are available for the setting: 5  enable :static, :session 6  set :root, File.dirname(__FILE__) 7  8  # each subclass has its own private middleware stack: 9  #use Rack::Deflater 10  11  get '/sinatra' do 12  &quot;Hello, sinatra&quot; 13  end 14 end
Speed contrast:  sequel and metal Ubuntu 8.04, Intel Atom N270 @1.60GHz, 100 requests, development mode Traditional Rails MVC Requests per second:  16.69 [#/sec] (mean) Time per request:  59.923 [ms] (mean) Rails Metal Requests per second:  71.78 [#/sec] (mean) Time per request:  13.932 [ms] (mean) Sinatra standalone (  3 times of Rails Metal!  ) Requests per second:  208.39 [#/sec] (mean) Time per request:  4.799 [ms] (mean)
Questions?
Thank you! http://masterwujiang.javaeye.com/ my blog (Chinese only) http://github.com/nouse/ruby-off-rails/tree/master whole ruby files running in this presentation Jiang Wu  Shanghai on Rails  2009.3.14

Ruby off Rails---rack, sinatra and sequel

  • 1.
    Ruby off RailsRack, Sinatra and Sequel Jiang Wu 2009.3.14
  • 2.
    Outline Rack SinatraSequel Ruby off Rails Rails Metal: A way of fusion
  • 3.
    rack http://rack.rubyforge.net/ Rackaims to provide a minimal API for connecting web servers and web frameworks.
  • 4.
    Rack SPEC {&quot;HTTP_USER_AGENT&quot;=>&quot;curl/7.12.2...&quot;, &quot;REQUEST_URI&quot;=>&quot;http://ruby-lang.org/&quot;, &quot;QUERY_STRING&quot;=>&quot;&quot;, &quot;HTTP_ACCEPT&quot;=>&quot;*/*&quot;, &quot;REQUEST_METHOD&quot;=>&quot;GET&quot;, &quot;rack.input&quot; => '...', ... } call(env) [status, headers, body] to_i each each [String,String] String yields yields
  • 5.
    Rack middleware: processRESP RESP RESP Rack Middleware 1 Rack Middleware 3 Rack Middleware 2
  • 6.
    A rack middlewarecan do: Do nothing (usually after a condition judgment) Response directly Alter environment variables Alter response(body, headers and status code)
  • 7.
    Write your ownrack middleware nothing.ru middleware do nothing calc_time.ru add response time to body method_override.ru alter HTTP method
  • 8.
  • 9.
    sinatra program: infinity.rb1 require 'rubygems' 2 require 'sinatra'   3   4 use Rack::CommonLogger   5 use Rack::ShowExceptions   6   7 get '/' do   8   &quot;Hello, Sinatra&quot;   9 end 10 11 get '/version' do 12   &quot;infinity 0.1&quot; 13 end 14 15 get '/version/last' do 16   &quot;infinity beta 0.13&quot; 17 end
  • 10.
    sequel The DatabaseToolkit for Ruby sequel postgres://localhost/blog Your database is stored in DB... >> DB.tables => [:blogs, :tags] >> require 'logger' >> DB.logger = Logger.new(STDOUT) >> DB[:tags].filter(:count > 100).order( :name.desc).limit(5).all INFO -- : SELECT * FROM &quot;tags&quot; WHERE (&quot;count&quot; > 150) ORDER BY &quot;name&quot; DESC LIMIT 5 >> class Tag < Sequel::Model;end >> Tag.filter(:count > 150).order(:name.desc).limit(5).all
  • 11.
    sinatra + sequel:a simple note ruby notes.rb Just ONE file to run!
  • 12.
    Ruby off Railsjquery vs. prototype.js jquery UI vs. script.aculo.us extlib vs. ActiveSupport sequel vs. ActiveRecord sinatra vs. ActionPack pony vs. ActionMailer rest-client vs. ActiveResource
  • 13.
    Off Rails ifyou ... Hate the namespace pollution Prototype.js ActiveSupport ActiveRecord pollutes collection Want to use a dispatcher based on URL Hate the constraints Constraint of program structure Constraint of table structure Constraint of URL structure Want to speed up Speed up upload Speed up performance Speed up test performance
  • 14.
    On Rails ifyou ... Need mature plug-ins Need write-through cache(with support from Cache-money) Need existing view helpers Need help from community
  • 15.
    Rails metal: newin 2.3 If you have a Rails application that has service end points that need to be really, really fast. So fast that the few milliseconds that a trip through the Rails router and Action Controller path is too much. For this scenario, we’ve built a thin wrapper around the generic Rack middleware and given it a place in the hierarchy along with the name “ Metal ” . Introducing Rails Metal —— DHH
  • 16.
    Rails Metal: thecode “Hello World” Metal: class Poller < Rails::Rack::Metal def call(env) if env[&quot;PATH_INFO&quot;] =~ /^\/poller/ [200, {&quot;Content-Type&quot; => &quot;text/html&quot;}, &quot;Hello, World!&quot;] else [404, {&quot;Content-Type&quot; => &quot;text/html&quot;}, &quot;Not Found&quot;] end end end “ Hello World” controller: class OldPollerController < ApplicationController def poller render :text => &quot;Hello World!&quot; end end
  • 17.
    Rails Metal andsinatra 1 require 'sinatra/base' 2 3 class Hello < Sinatra::Base 4 # all options are available for the setting: 5 enable :static, :session 6 set :root, File.dirname(__FILE__) 7 8 # each subclass has its own private middleware stack: 9 #use Rack::Deflater 10 11 get '/sinatra' do 12 &quot;Hello, sinatra&quot; 13 end 14 end
  • 18.
    Speed contrast: sequel and metal Ubuntu 8.04, Intel Atom N270 @1.60GHz, 100 requests, development mode Traditional Rails MVC Requests per second: 16.69 [#/sec] (mean) Time per request: 59.923 [ms] (mean) Rails Metal Requests per second: 71.78 [#/sec] (mean) Time per request: 13.932 [ms] (mean) Sinatra standalone ( 3 times of Rails Metal! ) Requests per second: 208.39 [#/sec] (mean) Time per request: 4.799 [ms] (mean)
  • 19.
  • 20.
    Thank you! http://masterwujiang.javaeye.com/my blog (Chinese only) http://github.com/nouse/ruby-off-rails/tree/master whole ruby files running in this presentation Jiang Wu Shanghai on Rails 2009.3.14