0
Rack
Elan Meng
Caibangzi.com
IN-SRC Studio
http://www.mengyan.org/blog/
        @dreamwords
elanmeng@in-src.com
Thanks !!
Rack Sales?
Overview
• Why Rack
• What’s Rack
• Rack Middleware
• Rails on Rack
• Example
• Q &A
Problems
• Ruby is popular
• Different web servers (app servers)
• Different web frameworks
• each framework has to write ...
We hate duplication!
How?
Abstraction
 Interface
make the simplest
  possible API that
represents a generic
  web application
Request -> Response
Request
•   CGI Envrionment

•   {"HTTP_USER_AGENT"=>"curl/7.12.2 ..."
    "REMOTE_HOST"=>"127.0.0.1",
    "PATH_INFO"=>"/...
Response
  HTTP/1.1 302

Found Date: Sat, 27 Oct 2007 10:07:53 GMT
Server: Apache/2.0.54 (Debian GNU/Linux)
mod_ssl/2.0.54...
What’s Rack
• Duck-Type
• Ruby object that respond_to? :call
• One argument, the environment variable
• return values
 • s...
lambda { |env|
	 [
	 	 200,
	 	 {'Content-Type' => 'text/
plain', 'Content-Length' => '16'},
	 	 ["Beijing on Rails"]
	 ]
}
app = lambda { |env|
	 [
	 	 200,
	 	 {'Content-Type' => 'text/
plain', 'Content-Length' => ’16’},
	 	 ["Beijing on Rails"...
rackup config.ru
curl http://localhost:9292/
Beijing on Rails
%w(rubygems rack).each { |dep| require dep }

Rack::Handler::Mongrel.run(app, :Port =>
3000)
Rack Middleware


                  Framework
HTTP
                     APP
Rack Middleware


                  Framework
HTTP
                     APP




           Rack
module Rack
  class BeijingOnRails
    def initialize(app)
      @app = app
    end

    def call(env)
      ... ...
     ...
app = Rack::CommonLogger.new(
       Rack::ShowExceptions.new(
          Rack::ShowStatus.new(
          Rack::Lint.new(ap...
Rack Middleware


                      Framework
HTTP
                         APP




         Middleware
Rack Middleware

• Chain of Responsibilities
app = Rack::CommonLogger.new(
       Rack::ShowExceptions.new(
          Rack...
Rack Distribution

• Specification
• Handlers
• Adapters
• Middlewares
• Utilities
Rack - Specification
• Rack::Lint
specify "notices status errors" do
  lambda {
    Rack::Lint.new(lambda { |env|
         ...
Rack - Handlers
• CGI
• FastCGI
• Mongrel
• WEBrick
• Thin
• Passenger
• Unicorn
Rack - Adapters

• Camping
• Merb
• Rails
• Sinatra
• ......
Rack - Middleware

• Rack::Static & Rack::File
• Rack::CommonLogger
• Rack::Reloader
• Rack::ShowExceptions
Rack - Utilities
• Rackup
 • a useful tool for running Rack
    applications
• Rackup::Builder
 • DSL to configure middlewa...
app = Rack::Builder.new do

   use Rack::CommonLogger
   use Rack::ShowExceptions
   use Rack::ShowStatus
   use Rack::Lin...
Rails on Rack
The most important
change in Rails over the
 past year - its move to
     become Rack-
                  - Ben Scofield
Rails on Rack
• first commit - Ezra & Josh on June 2008
Rails on Rack
• Merb & Rails merge
• ActionController::Dispatcher.new
• ActionController::MiddlewareStack
• ActionControll...
app = Rack::Builder.new {
  use Rails::Rack::LogTailer unless options[:detach]
  use Rails::Rack::Debugger if options[:deb...
# RAILS_ROOT/config.ru
require "config/environment"

use Rails::Rack::LogTailer
use Rails::Rack::Static
run ActionControll...
Metal
• bypass some of the normal overhead of the
  Rails stack
• specify certain routes and code to execute
  when those ...
$ script/generate metal poller


class Poller
  def self.call(env)
    if env["PATH_INFO"] =~ /^/poller/
      [200, {"Con...
Rack::Metal
def call(env)
  @metals.keys.each do |app|
    result = app.call(env)
    return result unless result[0].to_i ...
Response Timer
module Rack
  class Runtime
    def initialize(app, name = nil)
      @app = app
      @header_name = "X-Runtime"
      @h...
http://github.com/rack/rack-contrib
CodeRack
• http://coderack.org/
• a competition to develop most useful and
  top quality Rack middlewares.
• 1 DAY LEFT
WRAP UP
Rack is a beautiful thing
                    - Ryan Bates
References

• Introducing Rack - Christian Neukirchen
• http://rack.rubyforge.org/
• RailsCasts 151: Rack Middleware
• htt...
Q &A

• Rack
• Ruby on Rails
• Caibangzi.com
• Mutual Fund & Investment
Why not simply string
•   Ruby 1.8

    •   String was a collection of bytes

    •   String’s :each method iterated over ...
Rack
Rack
Upcoming SlideShare
Loading in...5
×

Rack

3,471

Published on

By Meng Yan

Published in: Technology
0 Comments
5 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
3,471
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
44
Comments
0
Likes
5
Embeds 0
No embeds

No notes for slide

Transcript of "Rack"

  1. 1. Rack
  2. 2. Elan Meng
  3. 3. Caibangzi.com
  4. 4. IN-SRC Studio
  5. 5. http://www.mengyan.org/blog/ @dreamwords
  6. 6. elanmeng@in-src.com
  7. 7. Thanks !!
  8. 8. Rack Sales?
  9. 9. Overview • Why Rack • What’s Rack • Rack Middleware • Rails on Rack • Example • Q &A
  10. 10. Problems • Ruby is popular • Different web servers (app servers) • Different web frameworks • each framework has to write it’s own handlers to different web servers • Not only the handler
  11. 11. We hate duplication!
  12. 12. How?
  13. 13. Abstraction Interface
  14. 14. make the simplest possible API that represents a generic web application
  15. 15. Request -> Response
  16. 16. Request • CGI Envrionment • {"HTTP_USER_AGENT"=>"curl/7.12.2 ..." "REMOTE_HOST"=>"127.0.0.1", "PATH_INFO"=>"/", "HTTP_HOST"=>"ruby- lang.org", "SERVER_PROTOCOL"=>"HTTP/1.1", "SCRIPT_NAME"=>"", "REQUEST_PATH"=>"/", "REMOTE_ADDR"=>"127.0.0.1", "HTTP_VERSION"=>"HTTP/1.1", "REQUEST_URI"=>"http://ruby-lang.org/", "SERVER_PORT"=>"80", "HTTP_PRAGMA"=>"no- cache", "QUERY_STRING"=>"", "GATEWAY_INTERFACE"=>"CGI/1.1", "HTTP_ACCEPT"=>"*/*", "REQUEST_METHOD"=>"GET"}
  17. 17. Response HTTP/1.1 302 Found Date: Sat, 27 Oct 2007 10:07:53 GMT Server: Apache/2.0.54 (Debian GNU/Linux) mod_ssl/2.0.54 OpenSSL/0.9.7e Location: http://www.ruby-lang.org/ Content-Length: 209 Content-Type: text/html; charset=iso-8859-1 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>302 Found</title> </head> <body> <h1>Found</h1> <p>The document has moved <a href="http://www.ruby-lang.org/">here</a>. </p> </body></html>
  18. 18. What’s Rack • Duck-Type • Ruby object that respond_to? :call • One argument, the environment variable • return values • status - respond_to? :to_i • headers - respond_to? :each, yield key/ value • body - respond_to? :each, yield string
  19. 19. lambda { |env| [ 200, {'Content-Type' => 'text/ plain', 'Content-Length' => '16'}, ["Beijing on Rails"] ] }
  20. 20. app = lambda { |env| [ 200, {'Content-Type' => 'text/ plain', 'Content-Length' => ’16’}, ["Beijing on Rails"] ] } run app
  21. 21. rackup config.ru
  22. 22. curl http://localhost:9292/
  23. 23. Beijing on Rails
  24. 24. %w(rubygems rack).each { |dep| require dep } Rack::Handler::Mongrel.run(app, :Port => 3000)
  25. 25. Rack Middleware Framework HTTP APP
  26. 26. Rack Middleware Framework HTTP APP Rack
  27. 27. module Rack class BeijingOnRails def initialize(app) @app = app end def call(env) ... ... status, headers body = @app.call(env) ... ... [status, header, body] end end end
  28. 28. app = Rack::CommonLogger.new( Rack::ShowExceptions.new( Rack::ShowStatus.new( Rack::Lint.new(app))))
  29. 29. Rack Middleware Framework HTTP APP Middleware
  30. 30. Rack Middleware • Chain of Responsibilities app = Rack::CommonLogger.new( Rack::ShowExceptions.new( Rack::ShowStatus.new( Rack::Lint.new(app))))
  31. 31. Rack Distribution • Specification • Handlers • Adapters • Middlewares • Utilities
  32. 32. Rack - Specification • Rack::Lint specify "notices status errors" do lambda { Rack::Lint.new(lambda { |env| ["cc", {}, ""] }).call(env({})) }.should.raise(Rack::Lint::LintError). message.should.match(/must be >=100 seen as integer/) lambda { Rack::Lint.new(lambda { |env| [42, {}, ""] }).call(env({})) }.should.raise(Rack::Lint::LintError). message.should.match(/must be >=100 seen as integer/) end
  33. 33. Rack - Handlers • CGI • FastCGI • Mongrel • WEBrick • Thin • Passenger • Unicorn
  34. 34. Rack - Adapters • Camping • Merb • Rails • Sinatra • ......
  35. 35. Rack - Middleware • Rack::Static & Rack::File • Rack::CommonLogger • Rack::Reloader • Rack::ShowExceptions
  36. 36. Rack - Utilities • Rackup • a useful tool for running Rack applications • Rackup::Builder • DSL to configure middleware and build up applications easily
  37. 37. app = Rack::Builder.new do use Rack::CommonLogger use Rack::ShowExceptions use Rack::ShowStatus use Rack::Lint run MyRackApp.new end Rack::Handler::Mongrel.run app, :Port => 8080
  38. 38. Rails on Rack
  39. 39. The most important change in Rails over the past year - its move to become Rack- - Ben Scofield
  40. 40. Rails on Rack • first commit - Ezra & Josh on June 2008
  41. 41. Rails on Rack • Merb & Rails merge • ActionController::Dispatcher.new • ActionController::MiddlewareStack • ActionController -> Rack Middleware • ActionDispatch::Failsafe • ActionDispatch::ShowExceptions • Plugin -> Rack Middleware • Hoptoad_notifier plugin -> Rack::Hoptoad.
  42. 42. app = Rack::Builder.new { use Rails::Rack::LogTailer unless options[:detach] use Rails::Rack::Debugger if options[:debugger] map "/" do use Rails::Rack::Static run ActionController::Dispatcher.new end }.to_app
  43. 43. # RAILS_ROOT/config.ru require "config/environment" use Rails::Rack::LogTailer use Rails::Rack::Static run ActionController::Dispatcher.new rackup
  44. 44. Metal • bypass some of the normal overhead of the Rails stack • specify certain routes and code to execute when those routes are hit. • avoid the entirety of ActionController • Rails::Rack::Metal • ActionController::MiddlewareStack
  45. 45. $ script/generate metal poller class Poller def self.call(env) if env["PATH_INFO"] =~ /^/poller/ [200, {"Content-Type" => "text/html"}, ["Hello, World!"]] else [404, {"Content-Type" => "text/html"}, ["Not Found"]] end end end
  46. 46. Rack::Metal def call(env) @metals.keys.each do |app| result = app.call(env) return result unless result[0].to_i == 404 end @app.call(env) end
  47. 47. Response Timer
  48. 48. module Rack class Runtime def initialize(app, name = nil) @app = app @header_name = "X-Runtime" @header_name << "-#{name}" if name end def call(env) start_time = Time.now status, headers, body = @app.call(env) request_time = Time.now - start_time if !headers.has_key?(@header_name) headers[@header_name] = "%0.6f" % request_time end [status, headers, body] end end end
  49. 49. http://github.com/rack/rack-contrib
  50. 50. CodeRack • http://coderack.org/ • a competition to develop most useful and top quality Rack middlewares. • 1 DAY LEFT
  51. 51. WRAP UP
  52. 52. Rack is a beautiful thing - Ryan Bates
  53. 53. References • Introducing Rack - Christian Neukirchen • http://rack.rubyforge.org/ • RailsCasts 151: Rack Middleware • http://heroku.com/how/architecture
  54. 54. Q &A • Rack • Ruby on Rails • Caibangzi.com • Mutual Fund & Investment
  55. 55. Why not simply string • Ruby 1.8 • String was a collection of bytes • String’s :each method iterated over lines of data • Ruby 1.9 • String is now a collection of encoded data. (Raw bytes and encoding information) • :each has been removed from String and it’s no longer Enumerable
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×