-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rails Boot Process #7
Comments
A Request/Response Process
begin
status, headers, body = app.call(env)
begin
send_headers request.out, status, headers
send_body request.out, body
ensure
body.close if body.respond_to? :close
end
ensure
rack_input.close
request.finish
end
# railties/lib/rails/engine.rb#L519
# Define the Rack API for this engine.
def call(env)
req = build_request env
app.call req.env
end
...
def initialize(config = DEFAULT_CONFIG)
self.named_routes = NamedRouteCollection.new
self.resources_path_names = self.class.default_resources_path_names
self.default_url_options = {}
@config = config
@append = []
@prepend = []
@disable_clear_and_finalize = false
@finalized = false
@env_key = "ROUTES_#{object_id}_SCRIPT_NAME".freeze
@set = Journey::Routes.new
@router = Journey::Router.new @set
@formatter = Journey::Formatter.new self
end
...
def call(env)
req = make_request(env)
req.path_info = Journey::Router::Utils.normalize_path(req.path_info)
@router.serve(req)
end
...
def serve(req)
find_routes(req).each do |match, parameters, route|
set_params = req.path_parameters
path_info = req.path_info
script_name = req.script_name
unless route.path.anchored
req.script_name = (script_name.to_s + match.to_s).chomp('/')
req.path_info = match.post_match
req.path_info = "/" + req.path_info unless req.path_info.start_with? "/"
end
req.path_parameters = set_params.merge parameters
status, headers, body = route.app.serve(req)
if 'pass' == headers['X-Cascade']
req.script_name = script_name
req.path_info = path_info
req.path_parameters = set_params
next
end
return [status, headers, body]
end
...
def custom_routes
routes.custom_routes
end
...
def find_routes req
routes = filter_routes(req.path_info).concat custom_routes.find_all { |r|
r.path.match(req.path_info)
}
routes =
if req.head?
match_head_routes(routes, req)
else
match_routes(routes, req)
end
routes.sort_by!(&:precedence)
routes.map! { |r|
match_data = r.path.match(req.path_info)
path_parameters = r.defaults.dup
match_data.names.zip(match_data.captures) { |name,val|
path_parameters[name.to_sym] = Utils.unescape_uri(val) if val
}
[match_data, path_parameters, r]
}
end
def initialize(set, ast, defaults, controller, default_action, modyoule, to, formatted, scope_constraints, blocks, via, options_constraints, anchor, options)
@defaults = defaults
@set = set
@to = to
@default_controller = controller
@default_action = default_action
@ast = ast
@anchor = anchor
@via = via
@internal = options[:internal]
path_params = ast.find_all(&:symbol?).map(&:to_sym)
options = add_wildcard_options(options, formatted, ast)
options = normalize_options!(options, path_params, modyoule)
split_options = constraints(options, path_params)
constraints = scope_constraints.merge Hash[split_options[:constraints] || []]
if options_constraints.is_a?(Hash)
@defaults = Hash[options_constraints.find_all { |key, default|
URL_OPTIONS.include?(key) && (String === default || Fixnum === default)
}].merge @defaults
@blocks = blocks
constraints.merge! options_constraints
else
@blocks = blocks(options_constraints)
end
requirements, conditions = split_constraints path_params, constraints
verify_regexp_requirements requirements.map(&:last).grep(Regexp)
formats = normalize_format(formatted)
@requirements = formats[:requirements].merge Hash[requirements]
@conditions = Hash[conditions]
@defaults = formats[:defaults].merge(@defaults).merge(normalize_defaults(options))
@required_defaults = (split_options[:required_defaults] || []).map(&:first)
end
def make_route(name, precedence)
route = Journey::Route.new(name,
application,
path,
conditions,
required_defaults,
defaults,
request_method,
precedence,
@internal)
route
end
def application
app(@blocks)
end
def app(blocks)
if to.is_a?(Class) && to < ActionController::Metal
Routing::RouteSet::StaticDispatcher.new to
else
if to.respond_to?(:call)
Constraints.new(to, blocks, Constraints::CALL)
elsif blocks.any?
Constraints.new(dispatcher(defaults.key?(:controller)), blocks, Constraints::SERVE)
else
dispatcher(defaults.key?(:controller))
end
end
end
...
def draw(&block)
clear! unless @disable_clear_and_finalize
eval_block(block)
finalize! unless @disable_clear_and_finalize
nil
end
...
def eval_block(block)
mapper = Mapper.new(self)
if default_scope
mapper.with_default_scope(default_scope, &block)
else
mapper.instance_exec(&block)
end
end
private :eval_block
# Makes the controller a Rack endpoint that runs the action in the given
# +env+'s +action_dispatch.request.path_parameters+ key.
def self.call(env)
req = ActionDispatch::Request.new env
action(req.path_parameters[:action]).call(env)
end
class << self; deprecate :call; end
# Returns a Rack endpoint for the given action name.
def self.action(name)
if middleware_stack.any?
middleware_stack.build(name) do |env|
req = ActionDispatch::Request.new(env)
res = make_response! req
new.dispatch(name, req, res)
end
else
lambda { |env|
req = ActionDispatch::Request.new(env)
res = make_response! req
new.dispatch(name, req, res)
}
end
end
# Direct dispatch to the controller. Instantiates the controller, then
# executes the action named +name+.
def self.dispatch(name, req, res)
if middleware_stack.any?
middleware_stack.build(name) { |env| new.dispatch(name, req, res) }.call req.env
else
new.dispatch(name, req, res)
end
end |
The
Rails
Commandwhich rails
which _rails_command
bin/rails
: base on your rails app's root directorysummary in
bin/rails
Spring
: is a Rails application preloader. It speeds up development by keeping your application running in the background so you don't need to boot it every time you run a test, rake task or migration.APP_PATH
: set the absolute path of Rails Application.require_relative '../config/boot'
: execute bunder setup, install required gemsrequire 'rails/commands'
: load rails commandsCommands Tasks
bin/rails: Rails::CommandsTasks.new(ARGV).run_command!(command)
: run specified command. https://github.com/rails/rails/blob/master/railties/lib/rails/commands.rbrequire 'rails/commands/commands_tasks'
: https://github.com/rails/rails/blob/master/railties/lib/rails/commands/commands_tasks.rbsummary in
rails server
set_application_directory!
: set application directory, locateconfig.ru
rack file.require_command!("server")
: require rails server, inherited from Rack Server.server.start
: start rack server, than the app in runningRack Server, #4
lib/rack/server.rb
: the generic Rack Server. https://github.com/rack/rack/blob/master/lib/rack/server.rbRack::Handler.default
: get the default rack handler. https://github.com/rack/rack/blob/master/lib/rack/handler.rb#L46rack/fastcgi.rb
: https://github.com/rack/rack/blob/master/lib/rack/handler/fastcgi.rbconfig.ru
: the rack config fileconfig/environment.rb
: load and initialize Rails applicationconfig/application.rb
: the Rails applicationRails Application
Rails::Application
: https://github.com/rails/rails/blob/master/railties/lib/rails/application.rbRails::Engine
: the Rails Engine. https://github.com/rails/rails/blob/master/railties/lib/rails/engine.rbEngine#call
: the Rack Interface. https://github.com/rails/rails/blob/master/railties/lib/rails/engine.rb#L519Application booting process: https://github.com/rails/rails/blob/master/railties/lib/rails/application.rb#L36
Reference
The text was updated successfully, but these errors were encountered: