• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Rack
 

Rack

on

  • 4,065 views

By Meng Yan

By Meng Yan

Statistics

Views

Total Views
4,065
Views on SlideShare
4,057
Embed Views
8

Actions

Likes
4
Downloads
42
Comments
0

1 Embed 8

http://www.slideshare.net 8

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Rack Rack Presentation Transcript

    • 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 it’s own handlers to different web servers • Not only the handler
    • 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"=>"/", "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"}
    • 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>
    • 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
    • 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"] ] } run app
    • 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) ... ... status, headers body = @app.call(env) ... ... [status, header, body] end end end
    • app = Rack::CommonLogger.new( Rack::ShowExceptions.new( Rack::ShowStatus.new( Rack::Lint.new(app))))
    • Rack Middleware Framework HTTP APP Middleware
    • Rack Middleware • Chain of Responsibilities app = Rack::CommonLogger.new( Rack::ShowExceptions.new( Rack::ShowStatus.new( Rack::Lint.new(app))))
    • Rack Distribution • Specification • Handlers • Adapters • Middlewares • Utilities
    • 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
    • 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 middleware and build up applications easily
    • 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
    • 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 • ActionController -> Rack Middleware • ActionDispatch::Failsafe • ActionDispatch::ShowExceptions • Plugin -> Rack Middleware • Hoptoad_notifier plugin -> Rack::Hoptoad.
    • 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
    • # RAILS_ROOT/config.ru require "config/environment" use Rails::Rack::LogTailer use Rails::Rack::Static run ActionController::Dispatcher.new rackup
    • 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
    • $ 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
    • 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
    • Response Timer
    • 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
    • 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 • http://heroku.com/how/architecture
    • 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 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