This class is capable of spawning Ruby on Rails application instances quickly. This is done by preloading the Ruby on Rails framework into memory, before spawning the application instances.

A single FrameworkSpawner instance can only hold a single Ruby on Rails framework version. So be careful when using FrameworkSpawner: the applications that you spawn through it must require the same RoR version. To handle multiple RoR versions, use multiple FrameworkSpawner instances.

FrameworkSpawner uses ApplicationSpawner internally.

Note: FrameworkSpawner may only be started asynchronously with AbstractServer#start. Starting it synchronously with AbstractServer#start_synchronously has not been tested.

Methods
Included Modules
Classes and Modules
Class Passenger::Railz::FrameworkSpawner::Error
Attributes
[RW] time An attribute, used internally. This should not be used outside Passenger.
Public Class methods
new(options = {})

Creates a new instance of FrameworkSpawner.

Valid options:

  • :version: The Ruby on Rails version to use. It is not checked whether this version is actually installed.
  • :vendor: The directory to the vendor Rails framework to use. This is usually something like "/webapps/foo/vendor/rails".

It is not allowed to specify both version and vendor.

Note that the specified Rails framework will be loaded during the entire life time of the FrameworkSpawner server. If you wish to reload the Rails framework‘s code, then restart the server by calling AbstractServer#stop and AbstractServer#start.

    # File lib/passenger/railz/framework_spawner.rb, line 64
64:         def initialize(options = {})
65:                 if !options.respond_to?('[]''[]')
66:                         raise ArgumentError, "The 'options' argument not seem to be an options hash"
67:                 end
68:                 @version = options[:version]
69:                 @vendor = options[:vendor]
70:                 if !@version && !@vendor
71:                         raise ArgumentError, "Either the 'version' or the 'vendor' option must specified"
72:                 elsif @version && @vendor
73:                         raise ArgumentError, "It is not allowed to specify both the 'version' and the 'vendor' options"
74:                 end
75:                 
76:                 super()
77:                 define_message_handler(:spawn_application, :handle_spawn_application)
78:                 define_message_handler(:reload, :handle_reload)
79:         end
Public Instance methods
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 by a FrameworkSpawner. 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:

     # File lib/passenger/railz/framework_spawner.rb, line 171
171:         def reload(app_root = nil)
172:                 if app_root.nil?
173:                         server.write("reload")
174:                 else
175:                         server.write("reload", normalize_path(app_root))
176:                 end
177:         rescue SystemCallError, IOError, SocketError
178:                 raise Error, "The framework spawner server exited unexpectedly"
179:         end
spawn_application(app_root, lower_privilege = true, lowest_user = "nobody", environment = "production")

Spawn a RoR application using the Ruby on Rails framework version associated with this FrameworkSpawner. When successful, an Application object will be returned, which represents the spawned RoR application.

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

FrameworkSpawner 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:

Raises:

     # File lib/passenger/railz/framework_spawner.rb, line 129
129:         def spawn_application(app_root, lower_privilege = true, lowest_user = "nobody", environment = "production")
130:                 app_root = normalize_path(app_root)
131:                 assert_valid_app_root(app_root)
132:                 exception_to_propagate = nil
133:                 begin
134:                         server.write("spawn_application", app_root, lower_privilege, lowest_user, environment)
135:                         result = server.read
136:                         if result.nil?
137:                                 raise IOError, "Connection closed"
138:                         end
139:                         if result[0] == 'exception'
140:                                 raise unmarshal_exception(server.read_scalar)
141:                         else
142:                                 pid, listen_socket_name, using_abstract_namespace = server.read
143:                                 if pid.nil?
144:                                         raise IOError, "Connection closed"
145:                                 end
146:                                 owner_pipe = server.recv_io
147:                                 return Application.new(app_root, pid, listen_socket_name,
148:                                         using_abstract_namespace == "true", owner_pipe)
149:                         end
150:                 rescue SystemCallError, IOError, SocketError => e
151:                         raise Error, "The framework spawner server exited unexpectedly"
152:                 end
153:         end
start()

Overrided from AbstractServer#start.

May raise these additional exceptions:

     # File lib/passenger/railz/framework_spawner.rb, line 86
 86:         def start
 87:                 super
 88:                 begin
 89:                         status = server.read[0]
 90:                         if status == 'exception'
 91:                                 child_exception = unmarshal_exception(server.read_scalar)
 92:                                 stop
 93:                                 if @version
 94:                                         message = "Could not load Ruby on Rails framework version #{@version}: " <<
 95:                                                 "#{child_exception.class} (#{child_exception.message})"
 96:                                 else
 97:                                         message = "Could not load Ruby on Rails framework at '#{@vendor}': " <<
 98:                                                 "#{child_exception.class} (#{child_exception.message})"
 99:                                 end
100:                                 options = { :vendor => @vendor, :version => @version }
101:                                 raise FrameworkInitError.new(message, child_exception, options)
102:                         end
103:                 rescue IOError, SystemCallError, SocketError
104:                         stop
105:                         raise Error, "The framework spawner server exited unexpectedly"
106:                 end
107:         end