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.



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

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.



59
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
# File 'lib/phusion_passenger/rack/application_spawner.rb', line 59

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.



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

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.



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

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