Parent

Included Modules

Class Index [+]

Quicksearch

PhusionPassenger::Rack::ApplicationSpawner

Class for spawning Rack applications.

Public Class Methods

spawn_application(*args) click to toggle source
    # File lib/phusion_passenger/rack/application_spawner.rb, line 39
39:         def self.spawn_application(*args)
40:                 @@instance ||= ApplicationSpawner.new
41:                 @@instance.spawn_application(*args)
42:         end

Public Instance Methods

spawn_application(app_root, options = {}) click to toggle source

Spawn an instance of the given Rack application. When successful, an Application object will be returned, which represents the spawned application.

Accepts the same options as Railz::ApplicationSpawner#initialize.

Raises:

  • AppInitError: The Rack application raised an exception or called exit() during startup.

  • SystemCallError, IOError, SocketError: Something went wrong.

    # File lib/phusion_passenger/rack/application_spawner.rb, line 54
54:         def spawn_application(app_root, options = {})
55:                 options = sanitize_spawn_options(options)
56:                 
57:                 a, b = UNIXSocket.pair
58:                 pid = safe_fork(self.class.to_s, true) do
59:                         a.close
60:                         
61:                         file_descriptors_to_leave_open = [0, 1, 2, b.fileno]
62:                         NativeSupport.close_all_file_descriptors(file_descriptors_to_leave_open)
63:                         close_all_io_objects_for_fds(file_descriptors_to_leave_open)
64:                         
65:                         run(MessageChannel.new(b), app_root, options)
66:                 end
67:                 b.close
68:                 Process.waitpid(pid) rescue nil
69:                 
70:                 channel = MessageChannel.new(a)
71:                 unmarshal_and_raise_errors(channel, !!options["print_exceptions"], "rack")
72:                 
73:                 # No exception was raised, so spawning succeeded.
74:                 pid, socket_name, socket_type = channel.read
75:                 if pid.nil?
76:                         raise IOError, "Connection closed"
77:                 end
78:                 owner_pipe = channel.recv_io
79:                 return Application.new(@app_root, pid, socket_name,
80:                         socket_type, owner_pipe)
81:         end

Private Instance Methods

load_rack_app() click to toggle source
     # File lib/phusion_passenger/rack/application_spawner.rb, line 141
141:         def load_rack_app
142:                 # Load Rack inside the spawned child process so that the spawn manager
143:                 # itself doesn't preload Rack. This is necessary because some broken
144:                 # Rails apps explicitly specify a Rack version as dependency.
145:                 require 'rack'
146:                 rackup_code = ::File.read("config.ru")
147:                 eval("Rack::Builder.new {( #{rackup_code}\n )}.to_app", TOPLEVEL_BINDING, "config.ru")
148:         end
run(channel, app_root, options) click to toggle source
     # File lib/phusion_passenger/rack/application_spawner.rb, line 84
 84:         def run(channel, app_root, options)
 85:                 $0 = "Rack: #{app_root}"
 86:                 app = nil
 87:                 success = report_app_init_status(channel) do
 88:                         ENV['RACK_ENV'] = options["environment"]
 89:                         ENV['RAILS_ENV'] = options["environment"]
 90:                         if options["base_uri"] && options["base_uri"] != "/"
 91:                                 ENV['RACK_BASE_URI'] = options["base_uri"]
 92:                                 ENV['RAILS_RELATIVE_URL_ROOT'] = options["base_uri"]
 93:                         end
 94:                         Dir.chdir(app_root)
 95:                         if options["environment_variables"]
 96:                                 set_passed_environment_variables(options["environment_variables"])
 97:                         end
 98:                         if options["lower_privilege"]
 99:                                 lower_privilege('config.ru', options["lowest_user"])
100:                         end
101:                         # Make sure RubyGems uses any new environment variable values
102:                         # that have been set now (e.g. $HOME, $GEM_HOME, etc) and that
103:                         # it is able to detect newly installed gems.
104:                         Gem.clear_paths
105:                         setup_bundler_support
106:                         app = load_rack_app
107:                 end
108:                 
109:                 if success
110:                         reader, writer = IO.pipe
111:                         begin
112:                                 handler = RequestHandler.new(reader, app, options)
113:                                 channel.write(Process.pid, handler.socket_name,
114:                                         handler.socket_type)
115:                                 channel.send_io(writer)
116:                                 writer.close
117:                                 channel.close
118:                                 
119:                                 PhusionPassenger.call_event(:starting_worker_process)
120:                                 handler.main_loop
121:                         ensure
122:                                 channel.close rescue nil
123:                                 writer.close rescue nil
124:                                 handler.cleanup rescue nil
125:                                 PhusionPassenger.call_event(:stopping_worker_process)
126:                         end
127:                 end
128:         end
set_passed_environment_variables(encoded_environment_variables) click to toggle source
     # File lib/phusion_passenger/rack/application_spawner.rb, line 130
130:         def set_passed_environment_variables(encoded_environment_variables)
131:                 env_vars_string = encoded_environment_variables.unpack("m").first
132:                 # Prevent empty string as last item from b0rking the Hash[...] statement.
133:                 # See comment in Hooks.cpp (sendHeaders) for details.
134:                 env_vars_string << "_\00__"
135:                 env_vars = Hash[*env_vars_string.split("\00"")]
136:                 env_vars.each_pair do |key, value|
137:                         ENV[key] = value
138:                 end
139:         end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.