Rails Startup Process (I) code Process Overview

Source: Internet
Author: User

Preface

Rails 3 has many new terms, such as railtie, engine, and application, which are closely related to the rails Startup Process and gem development, try to analyze the Startup Process of rails 3 and give yourself an explanation.

Enter:

Rails s

Start. First, let's see what rails is in this command:

$ which rails

/Home/tomwang/. rvm/gems/ruby-1.9.3-p194 @ rails323/bin/rails

The STARTUP script is as follows:

#!/usr/bin/env ruby## This file was generated by RubyGems.## The application 'railties' is installed as part of a gem, and# this file is here to facilitate running it.#require 'rubygems'version = ">= 0"if ARGV.first  str = ARGV.first  str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding  if str =~ /\A_(.*)_\z/    version = $1    ARGV.shift  endendgem 'railties', versionload Gem.bin_path('railties', 'rails', version)

This file mainly involves two tasks:

  • Import the railties gem, which is the core concept in rails 3 and will be analyzed in more detail later.
  • Load railties another rails script under this gem:/home/tomwang/. rvm/gems/ruby-1.9.3-p194 @ rails323/gems/railties-3.2.3/bin/rails

Its content is as follows:

#!/usr/bin/env rubyif File.exists?(File.join(File.expand_path('../../..', __FILE__), '.git'))  railties_path = File.expand_path('../../lib', __FILE__)  $:.unshift(railties_path)endrequire "rails/cli"

This rails is mainly require.

"railties-3.2.3/lib/rails/cli.rb "

The content of this file is as follows:

require 'rbconfig'require 'rails/script_rails_loader'  # If we are inside a Rails application this method performs an exec and thus# the rest of this script is not run.Rails::ScriptRailsLoader.exec_script_rails!

The function executed in the last row is as follows:

Module rails module scriptrailsloader Ruby = file. join (* rbconfig: config. values_at ("bindir", "ruby_install_name") + rbconfig: config ["exeext"] script_rails = file. join ('script', 'rails ') def self.exe c_script_rails! CWD = dir. pwd return unless in_rails_application? | In_rails_application_subdirectory? Exec Ruby, script_rails, * argv if in_rails_application? # Finally run script/rails dir in our project directory. chdir (".. ") Do # recurse in a chdir block: if the search fails we want to be sure # The application is generated in the original working directory. exec_script_rails! Unless CWD = dir. pwd end rescue systemcallerror # cocould not chdir, no problem just return end def self. in_rails_application? File. exists? (Script_rails) end def self. in_rails_application_subdirectory? (Path = pathname. New (dir. pwd) file. exists? (File. Join (path, script_rails) |! Path. Root? & In_rails_application_subdirectory? (Path. Parent) end

As shown in the preceding comments, script/rails in our own project directory is executed. Its content is as follows:

#!/usr/bin/env ruby                                                                                                 # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.         APP_PATH = File.expand_path('../../config/application',  __FILE__)                            require File.expand_path('../../config/boot',  __FILE__)                                                            require 'rails/commands'                                                                                            

It defines app_path, that is, our project file config/application. RB, and require config/boot. The boot file mainly initializes bundle. Then rails/commands (railties-3.2.3/lib/rails/commands. RB) the file is loaded in. Since the input command parameter is s, that is, server, we only display the corresponding code:

when 'server'                                                                                         # Change to the application's path if there is no config.ru file in current dir.                    # This allows us to run script/rails server from other directories, but still get                   # the main config.ru and properly set the tmp directory.                                            Dir.chdir(File.expand_path('../../', APP_PATH)) unless File.exists?(File.expand_path("config.ru"))                                                                                                      require 'rails/commands/server'                                                                     Rails::Server.new.tap { |server|                                                                      # We need to require application after the server sets environment,                                 # otherwise the --environment option given to the server won't propagate.                           require APP_PATH                                                                                    Dir.chdir(Rails.application.root)                                                                   server.start                                                                                      }                                                                                                 

Server. Start function:

def start                                                                          url = "#{options[:SSLEnable] ? 'https' : 'http'}://#{options[:Host]}:#{options[:Port]}"  puts "=> Booting #{ActiveSupport::Inflector.demodulize(server)}"                 puts "=> Rails #{Rails.version} application starting in #{Rails.env} on #{url}"  puts "=> Call with -d to detach" unless options[:daemonize]  trap(:INT) { exit }  puts "=> Ctrl-C to shutdown server" unless options[:daemonize]  #Create required tmp directories if not found                                    %w(cache pids sessions sockets).each do |dir_to_make|                              FileUtils.mkdir_p(Rails.root.join('tmp', dir_to_make))                         end                                                                                puts 'server start ---'  superensure  # The '-h' option calls exit before @options is set.                             # If we call 'options' with it unset, we get double help banners.                puts 'Exiting' unless @options && options[:daemonize]                          end                                                                              

The final super will call the Rack: Server # Start method:

def start &blk  if options[:warn]    $-w = true                                                     end                                                              if includes = options[:include]    $LOAD_PATH.unshift(*includes)                                  end  if library = options[:require]                                     require library  end  if options[:debug]    $DEBUG = true                                                    require 'pp'    p options[:server]                                               pp wrapped_app    pp app  end  # Touch the wrapped app, so that the config.ru is loaded before  # daemonization (i.e. before chdir, etc).                        wrapped_app  daemonize_app if options[:daemonize]                             write_pid if options[:pid]  trap(:INT) do    if server.respond_to?(:shutdown)                                   server.shutdown    else                                                               exit    end                                                            end  server.run wrapped_app, options, &blkend

Wrapped_app method finally calls Rack: Server # app:

def app  @app ||= begin                                                                  if !::File.exist? options[:config]                                              abort "configuration #{options[:config]} not found"                         end                                                                                  app, options = Rack::Builder.parse_file(self.options[:config], opt_parser)    self.options.merge! options    app  endend   

Because we didn't specify the config command line parameter, the system will take the default parameter and the: config.ru in the project directory. This file is related to rack (which will be discussed in detail later. This line of code imports config.ru with the following content:

require ::File.expand_path('../config/environment',  __FILE__)run Tao800Fire::Application                                   

It will then import the config/environment. RB file, in which our program will complete initialization:

# Load the rails application                        require File.expand_path('../application', __FILE__)                                                    # Initialize the rails application                  Tao800Fire::Application.initialize!

After the initialization is complete, we return
The last line of rack: Server # Start:

server.run wrapped_app, options, &blk

Because we didn't specify the server command line parameter, rack selects the default server for us:

def server                                                                         @_server ||= Rack::Handler.get(options[:server]) || Rack::Handler.default(options)end                                                                              
def self.default(options = {})          # Guess.                              if ENV.include?("PHP_FCGI_CHILDREN")    # We already speak FastCGI            options.delete :File                  options.delete :Port                                                        Rack::Handler::FastCGI              elsif ENV.include?("REQUEST_METHOD")    Rack::Handler::CGI                  else                                    begin                                   Rack::Handler::Thin                 rescue LoadError                        Rack::Handler::WEBrick              end                                 end                                 end                                   

Generally, webrick is used unless you have installed other application servers. Then webrick starts and displays the following information:

[2013-03-11 17:30:11] INFO  WEBrick 1.3.1[2013-03-11 17:30:11] INFO  ruby 1.9.3 (2012-04-20) [x86_64-linux][2013-03-11 17:30:11] INFO  WEBrick::HTTPServer#start: pid=28371 port=3000

Now, the entire startup process is complete. The next chapter will explain some key steps in detail and introduce some important concepts involved in the process.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.