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