Changeset 223

Show
Ignore:
Timestamp:
04/27/07 22:19:57 (2 years ago)
Author:
e.@brainspl.at
Message:

Huge performance increase check in. refactoring class reloading to be a noop in prodution has made merb hello world go from 298req/sec to 600req/sec on my macbook ;)

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/lib/merb.rb

    r208 r223  
    7070                    end   
    7171 
    72                        
     72module Mongrel::Const 
     73  HTTP_COOKIE   =  'HTTP_COOKIE'.freeze 
     74  QUERY_STRING  =  'QUERY_STRING'.freeze 
     75  CONTENT_TYPE_TEXT_HTML_HASH = {'Content-Type' =>'text/html'} 
     76  APPLICATION_JSON = 'application/json'.freeze  
     77  TEXT_JSON        = 'text/x-json'.freeze 
     78  UPCASE_CONTENT_TYPE = 'CONTENT_TYPE'.freeze 
     79end   
    7380          
    7481lib = File.join(__DIR__, 'merb') 
  • trunk/lib/merb/core_ext.rb

    r193 r223  
    11corelib = __DIR__+'/merb/core_ext' 
    22 
    3 %w[ merb_class 
     3%w[ merb_inflector 
     4    merb_class 
    45    merb_kernel 
    56    merb_object 
     
    1011    merb_numeric 
    1112    merb_symbol 
     13     
    1214  ].each {|fn| require File.join(corelib, fn)} 
  • trunk/lib/merb/core_ext/merb_class.rb

    r127 r223  
    7676 
    7777  def shared_attributes 
    78     @shared_attributes ||= {} 
     78    @shared_attributes ||= EMPTY_INHERITABLE_ATTRIBUTES 
    7979  end 
    8080   
    8181  def write_shared_attribute(key, value) 
     82    if shared_attributes.equal?(EMPTY_INHERITABLE_ATTRIBUTES) 
     83      @shared_attributes = {} 
     84    end 
    8285    shared_attributes[key] = value 
    8386  end 
     
    8891   
    8992  def reset_shared_attributes 
    90     shared_attributes.clear 
     93    shared_attributes = EMPTY_INHERITABLE_ATTRIBUTES 
    9194  end 
    9295 
    9396  private  
     97   
     98    # Prevent this constant from being created multiple times 
     99    EMPTY_INHERITABLE_ATTRIBUTES = {}.freeze unless const_defined?(:EMPTY_INHERITABLE_ATTRIBUTES) 
     100   
    94101    def inherited_with_shared_attributes(child) 
    95102      inherited_without_shared_attributes(child) if respond_to?(:inherited_without_shared_attributes) 
    96        
    97       new_shared_attributes = shared_attributes.inject({}) do |memo, (key, value)| 
    98         memo.update(key => (value.dup rescue value)) 
     103 
     104      if shared_attributes.equal?(EMPTY_INHERITABLE_ATTRIBUTES) 
     105        new_shared_attributes = EMPTY_INHERITABLE_ATTRIBUTES 
     106      else 
     107        new_shared_attributes = shared_attributes.inject({}) do |memo, (key, value)| 
     108          memo.update(key => (value.dup rescue value)) 
     109        end 
    99110      end 
    100111       
  • trunk/lib/merb/core_ext/merb_string.rb

    r125 r223  
    11class String 
    2    
    3   # reloads controller classes on each request if 
    4   # :allow_reloading is set to true in the config 
    5   # file or command line options. 
    6   def import 
    7     if Merb::Server.allow_reloading 
    8       Object.send(:remove_const, self.camel_case.intern) rescue nil 
    9       load(self.snake_case  + '.rb') 
    10     else   
    11       require(self.snake_case) 
    12     end 
    13   end 
    142   
    153  # "FooBar".snake_case #=> "foo_bar" 
  • trunk/lib/merb/merb_controller.rb

    r216 r223  
    2424 
    2525    MULTIPART_REGEXP = /\Amultipart\/form-data.*boundary=\"?([^\";,]+)/n.freeze 
    26          
     26     
    2727    # parses the http request into params, headers and cookies 
    2828    # that you can use in your controller classes. Also handles 
     
    3131    def initialize(request, env, args, response) 
    3232      @env = MerbHash[env.to_hash] 
    33       @status, @method, @response, @headers = 200, (env['REQUEST_METHOD']||'GET').downcase.to_sym, response, 
    34           {'Content-Type' =>'text/html'} 
    35       cookies = query_parse(@env['HTTP_COOKIE'], ';,') 
    36       querystring = query_parse(@env['QUERY_STRING']) 
    37        
    38       if MULTIPART_REGEXP =~ @env['CONTENT_TYPE'] && @method == :post 
     33      @status, @method, @response, @headers = 200, (env[Mongrel::Const::REQUEST_METHOD]||Mongrel::Const::GET).downcase.to_sym, response, 
     34          Mongrel::Const::CONTENT_TYPE_TEXT_HTML_HASH 
     35      cookies = query_parse(@env[Mongrel::Const::HTTP_COOKIE], ';,') 
     36      querystring = query_parse(@env[Mongrel::Const::QUERY_STRING]) 
     37       
     38      if MULTIPART_REGEXP =~ @env[Mongrel::Const::UPCASE_CONTENT_TYPE] && @method == :post 
    3939        querystring.update(parse_multipart(request, $1)) 
    4040      elsif @method == :post 
    41         if ['application/json', 'text/x-json'].include?(@env['CONTENT_TYPE']) 
     41        if [Mongrel::Const::APPLICATION_JSON, Mongrel::Const::TEXT_JSON].include?(@env[Mongrel::Const::UPCASE_CONTENT_TYPE]) 
    4242          MERB_LOGGER.info("JSON Request") 
    4343          json = JSON.parse(request.read || "") || {} 
  • trunk/lib/merb/merb_dispatcher.rb

    r210 r223  
    5050        path = path.sub(/\/+/, '/').sub(/\?.*$/, '') 
    5151        path = path[0..-2] if (path[-1] == ?/) && path.size > 1 
    52         Merb::RouteMatcher.new.route_request(path) 
     52        Merb::RouteMatcher.route_request(path) 
    5353      end 
    5454       
     
    6262        end unless $TESTING 
    6363        begin 
    64           controller_name.import 
     64          unless MERB_ENV == 'production' 
     65            Object.send(:remove_const, controller_name.camel_case.intern) rescue nil 
     66            load(controller_name.snake_case + '.rb') 
     67          end 
    6568          return Object.const_get( controller_name.camel_case ).new(req, env, params, res) 
    6669        rescue RuntimeError 
     
    6972        end 
    7073      end 
    71      
     74 
    7275    end # end class << self 
    7376       
  • trunk/lib/merb/merb_router.rb

    r216 r223  
    11module Merb 
    2   begin 
    3     require 'active_support' 
    4   rescue  
    5     MERB_LOGGER.warn "You must have ActiveSupport installed to use merb restful routing\nNormal routing works fine without" 
    6   end 
     2 
    73  # Merb::RouteMatcher is the request routing mapper for the merb framework. 
    84  # You can define placeholder parts of the url with the :symbol notation. 
     
    2925      compile_router 
    3026    end   
    31      
    32     # init @sections for route segment recognition 
    33     def initialize 
    34       @sections = Hash.new 
    35     end   
    36      
    37     # all defined routes in their raw form. 
    38     def routes 
    39       @@routes 
    40     end   
    41      
     27 
    4228    # the final compiled lambda that gets used 
    4329    # as the body of the route_request method. 
     
    6450    # first route that matches wins. 
    6551    def self.compile_router 
    66       router_lambda = @@routes.inject("lambda{|path| \n  case path\n") { |m,r| 
     52      router_lambda = @@routes.inject("lambda{|path| \n  sections={}\n  case path\n") { |m,r| 
    6753        m << compile(r) 
    6854      } <<"  else\n    return {:controller=>'Noroutefound', :action=>'noroute'}\n  end\n}" 
    6955      @@compiled_statement = router_lambda 
    70       define_method(:route_request, &eval(router_lambda)) 
     56      meta_def(:route_request, &eval(router_lambda)) 
    7157    end   
    7258     
     
    8975          route[0].sub!(@@section_regexp, "([^\/,?]+)") 
    9076        end 
    91         code << "    @sections[:#{name}] = $#{count}\n" 
     77        code << "    sections[:#{name}] = $#{count}\n" 
    9278      end 
    9379      @@compiled_regexen << Regexp.new(route[0]) 
     
    9581      condition = "  when @@compiled_regexen[#{index}] " 
    9682      statement = "#{condition}\n#{code}" 
    97       statement << "    return #{route[1].inspect}.update(@sections)\n" 
     83      statement << "    return #{route[1].inspect}.update(sections)\n" 
    9884      statement 
    9985    end 
  • trunk/specs/merb/merb_dispatch_spec.rb

    r207 r223  
    220220  end 
    221221 
     222  specify "compile_statement should contain router lambda" do 
     223    Merb::RouteMatcher.compiled_statement.should_be.kind_of?(String) 
     224    Merb::RouteMatcher.compiled_statement.should =~ /lambda\{\|path/ 
     225    Merb::RouteMatcher.compiled_statement.should =~ /@@compiled_regexen/ 
     226    Merb::RouteMatcher.compiled_statement.should =~ /update\(sections\)/ 
     227  end 
     228   
    222229  specify "should handle request: GET /foo/bar and return Foo#bar" do 
    223230    controller, action = request(:get, '/foo/bar')