Class: PhusionPassenger::Rack::ApplicationSpawner

Inherits:
Object
  • Object
show all
Includes:
Utils
Defined in:
lib/phusion_passenger/rack/application_spawner.rb

Overview

Class for spawning Rack applications.

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.spawn_application(*args) ⇒ Object



39
40
41
42
# File 'lib/phusion_passenger/rack/application_spawner.rb', line 39

def self.spawn_application(*args)
  @@instance ||= ApplicationSpawner.new
  @@instance.spawn_application(*args)
end

Instance Method Details

#spawn_application(app_root, options = {}) ⇒ Object

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.



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/phusion_passenger/rack/application_spawner.rb', line 54

def spawn_application(app_root, 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)
    
    run(MessageChannel.new(b), app_root, options)
  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.
  pid, socket_name, socket_type = channel.read
  if pid.nil?
    raise IOError, "Connection closed"
  end
  owner_pipe = channel.recv_io
  return Application.new(@app_root, pid, socket_name,
    socket_type, owner_pipe)
end