Class: PhusionPassenger::Rack::ApplicationSpawner

Inherits:
AbstractServer show all
Extended by:
Utils
Includes:
DebugLogging, Utils
Defined in:
lib/phusion_passenger/rack/application_spawner.rb

Overview

Spawning of Rack applications.

Defined Under Namespace

Classes: Error

Instance Attribute Summary

Attributes inherited from AbstractServer

#ignore_password_errors, #max_idle_time, #next_cleaning_time, #password

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Utils

process_is_alive?

Methods included from DebugLogging

_log_device, debug, error, included, log_file=, log_level=, stderr_evaluator=, trace, warn

Methods inherited from AbstractServer

#connect, #server_pid, #start_synchronously, #started?, #stop

Constructor Details

#initialize(options) ⇒ ApplicationSpawner

The following options are accepted:

  • ‘app_root’

See SpawnManager#spawn_application for information about the options.



96
97
98
99
100
101
102
103
# File 'lib/phusion_passenger/rack/application_spawner.rb', line 96

def initialize(options)
	super()
	@options          = sanitize_spawn_options(options)
	@app_root         = @options["app_root"]
	@canonicalized_app_root = canonicalize_path(@app_root)
	self.max_idle_time = DEFAULT_APP_SPAWNER_MAX_IDLE_TIME
	define_message_handler(:spawn_application, :handle_spawn_application)
end

Class Method Details

.spawn_application(options = {}) ⇒ Object

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

Accepts the same options as SpawnManager#spawn_application.

Raises:

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

  • SystemCallError, IOError, SocketError: Something went wrong.



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/phusion_passenger/rack/application_spawner.rb', line 60

def self.spawn_application(options = {})
	options = sanitize_spawn_options(options)
	
	a, b = UNIXSocket.pair
	pid = safe_fork(self.class.to_s, true) do
		a.close
		
		file_descriptors_to_leave_open = [0, 1, 2, b.fileno]
		NativeSupport.close_all_file_descriptors(file_descriptors_to_leave_open)
		close_all_io_objects_for_fds(file_descriptors_to_leave_open)
		
		channel = MessageChannel.new(b)
		app = nil
		success = report_app_init_status(channel) do
			prepare_app_process('config.ru', options)
			app = load_rack_app
			after_loading_app_code(options)
		end
		if success
			start_request_handler(channel, app, false, options)
		end
	end
	b.close
	Process.waitpid(pid) rescue nil
	
	channel = MessageChannel.new(a)
	unmarshal_and_raise_errors(channel, options["print_exceptions"], "rack")
	
	# No exception was raised, so spawning succeeded.
	return AppProcess.read_from_channel(channel)
end

Instance Method Details

#spawn_application(options = {}) ⇒ Object

Spawns an instance of the Rack application. When successful, an AppProcess object will be returned, which represents the spawned Rack application.

options will be passed to the request handler’s constructor.

Raises:

  • AbstractServer::ServerNotStarted: The ApplicationSpawner server hasn’t already been started.

  • ApplicationSpawner::Error: The ApplicationSpawner server exited unexpectedly.



113
114
115
116
117
118
119
120
# File 'lib/phusion_passenger/rack/application_spawner.rb', line 113

def spawn_application(options = {})
	connect do |channel|
		channel.write("spawn_application", *options.to_a.flatten)
		return AppProcess.read_from_channel(channel)
	end
rescue SystemCallError, IOError, SocketError => e
	raise Error, "The application spawner server exited unexpectedly: #{e}"
end

#startObject

Overrided from AbstractServer#start.

May raise these additional exceptions:

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

  • ApplicationSpawner::Error: The ApplicationSpawner server exited unexpectedly.



128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/phusion_passenger/rack/application_spawner.rb', line 128

def start
	super
	begin
		channel = MessageChannel.new(@owner_socket)
		unmarshal_and_raise_errors(channel, @options["print_exceptions"])
	rescue IOError, SystemCallError, SocketError => e
		stop if started?
		raise Error, "The application spawner server exited unexpectedly: #{e}"
	rescue
		stop if started?
		raise
	end
end