The spawn manager is capable of spawning Ruby on Rails or Rack application instances. It acts like a simple fascade for the rest of the spawn manager system.

Note: SpawnManager may only be started synchronously with AbstractServer#start_synchronously. Starting asynchronously has not been tested. Don‘t forget to call cleanup after the server‘s main loop has finished.

Ruby on Rails optimizations ===

Spawning a Ruby on Rails application is usually slow. But SpawnManager will preload and cache Ruby on Rails frameworks, as well as application code, so subsequent spawns will be very fast.

Internally, SpawnManager uses Railz::FrameworkSpawner to preload and cache Ruby on Rails frameworks. Railz::FrameworkSpawner, in turn, uses Railz::ApplicationSpawner to preload and cache application code.

In case you‘re wondering why the namespace is "Railz" and not "Rails": it‘s to work around an obscure bug in ActiveSupport‘s Dispatcher.

Methods
Included Modules
Public Class methods
new()
    # File lib/passenger/spawn_manager.rb, line 48
48:         def initialize
49:                 super()
50:                 @spawners = {}
51:                 @lock = Mutex.new
52:                 @cond = ConditionVariable.new
53:                 @cleaner_thread = Thread.new do
54:                         cleaner_thread_main
55:                 end
56:                 define_message_handler(:spawn_application, :handle_spawn_application)
57:                 define_message_handler(:reload, :handle_reload)
58:                 define_signal_handler('SIGHUP', :reload)
59:                 
60:                 GC.start
61:                 if GC.copy_on_write_friendly?
62:                         # Preload libraries for copy-on-write semantics.
63:                         require 'base64'
64:                         require 'passenger/application'
65:                         require 'passenger/railz/framework_spawner'
66:                         require 'passenger/railz/application_spawner'
67:                         require 'passenger/rack/application_spawner'
68:                         require 'passenger/html_template'
69:                         require 'passenger/platform_info'
70:                         require 'passenger/exceptions'
71:                         
72:                         # Commonly used libraries.
73:                         ['mysql', 'sqlite3'].each do |lib|
74:                                 begin
75:                                         require lib
76:                                 rescue LoadError
77:                                         # Do nothing; ignore if not present.
78:                                 end
79:                         end
80:                 end
81:         end
Public Instance methods
cleanup()

Cleanup resources. Should be called when this SpawnManager is no longer needed.

     # File lib/passenger/spawn_manager.rb, line 173
173:         def cleanup
174:                 @lock.synchronize do
175:                         @cond.signal
176:                 end
177:                 @cleaner_thread.join
178:                 @lock.synchronize do
179:                         @spawners.each_value do |spawner|
180:                                 if spawner.started?
181:                                         spawner.stop
182:                                 end
183:                         end
184:                         @spawners.clear
185:                 end
186:         end
reload(app_root = nil)

Remove the cached application instances at the given application root. If nil is specified as application root, then all cached application instances will be removed, no matter the application root.

Long description: Application code might be cached in memory. But once it a while, it will be necessary to reload the code for an application, such as after deploying a new version of the application. This method makes sure that any cached application code is removed, so that the next time an application instance is spawned, the application code will be freshly loaded into memory.

Raises AbstractServer::SpawnError if something went wrong.

     # File lib/passenger/spawn_manager.rb, line 144
144:         def reload(app_root = nil)
145:                 if app_root
146:                         begin
147:                                 app_root = normalize_path(app_root)
148:                         rescue ArgumentError
149:                         end
150:                 end
151:                 @lock.synchronize do
152:                         if app_root
153:                                 # Delete associated ApplicationSpawner.
154:                                 key = "app:#{app_root}"
155:                                 spawner = @spawners[key]
156:                                 if spawner
157:                                         if spawner.started?
158:                                                 spawner.stop
159:                                         end
160:                                         @spawners.delete(key)
161:                                 end
162:                         end
163:                         @spawners.each_value do |spawner|
164:                                 # Reload FrameworkSpawners.
165:                                 if spawner.respond_to?(:reload)
166:                                         spawner.reload(app_root)
167:                                 end
168:                         end
169:                 end
170:         end
spawn_application(app_root, lower_privilege = true, lowest_user = "nobody", environment = "production", spawn_method = "smart", app_type = "rails")

Spawn a RoR application When successful, an Application object will be returned, which represents the spawned RoR application.

See Railz::ApplicationSpawner.new for an explanation of the lower_privilege, lowest_user and environment parameters.

The spawn_method argument may be one of "smart" or "conservative". When "smart" is specified (the default), SpawnManager will internally cache the code of applications, in order to speed up future spawning attempts. This implies that, if you‘ve changed the application‘s code, you must do one of these things:

Caching however can be incompatible with some applications.

The "conservative" spawning method does not involve any caching at all. Spawning will be slower, but is guaranteed to be compatible with all applications.

Raises:

  • ArgumentError: app_root doesn‘t appear to be a valid Ruby on Rails application root.
  • VersionNotFound: The Ruby on Rails framework version that the given application requires is not installed.
  • AbstractServer::ServerError: One of the server processes exited unexpectedly.
  • FrameworkInitError: The Ruby on Rails framework that the application requires could not be loaded.
  • AppInitError: The application raised an exception or called exit() during startup.
     # File lib/passenger/spawn_manager.rb, line 107
107:         def spawn_application(app_root, lower_privilege = true, lowest_user = "nobody",
108:                               environment = "production", spawn_method = "smart",
109:                               app_type = "rails")
110:                 if app_type == "rack"
111:                         if !defined?(Rack::ApplicationSpawner)
112:                                 require 'passenger/rack/application_spawner'
113:                         end
114:                         return Rack::ApplicationSpawner.spawn_application(app_root,
115:                                 lower_privilege, lowest_user, environment)
116:                 elsif app_type == "wsgi"
117:                         require 'passenger/wsgi/application_spawner'
118:                         return WSGI::ApplicationSpawner.spawn_application(app_root,
119:                                 lower_privilege, lowest_user, environment)
120:                 else
121:                         if !defined?(Railz::FrameworkSpawner)
122:                                 require 'passenger/application'
123:                                 require 'passenger/railz/framework_spawner'
124:                                 require 'passenger/railz/application_spawner'
125:                         end
126:                         return spawn_rails_application(app_root, lower_privilege, lowest_user,
127:                                 environment, spawn_method)
128:                 end
129:         end