Class PhusionPassenger::ClassicRails::FrameworkSpawner
In: lib/phusion_passenger/classic_rails/framework_spawner.rb
Parent: AbstractServer

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

new   reload   spawn_application   start  

Included Modules

Utils

Classes and Modules

Class PhusionPassenger::ClassicRails::FrameworkSpawner::Error

Public Class methods

Creates a new instance of FrameworkSpawner.

Extra supported options:

  • framework_version: The Ruby on Rails version to use. It is not checked whether this version is actually installed.

All other options will be passed on to ApplicationSpawner and RequestHandler.

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.

[Source]

    # File lib/phusion_passenger/classic_rails/framework_spawner.rb, line 66
66:         def initialize(options = {})
67:                 if !options.respond_to?('[]''[]')
68:                         raise ArgumentError, "The 'options' argument does not seem to be an options hash"
69:                 end
70:                 @framework_version = options["framework_version"]
71:                 if options.has_key?("print_framework_loading_exceptions")
72:                         @print_framework_loading_exceptions = options["print_framework_loading_exceptions"]
73:                 else
74:                         @print_framework_loading_exceptions = true
75:                 end
76:                 if !@framework_version
77:                         raise ArgumentError, "The 'framework_version' option must specified"
78:                 end
79:                 
80:                 super()
81:                 @options = options
82:                 self.max_idle_time = DEFAULT_FRAMEWORK_SPAWNER_MAX_IDLE_TIME
83:                 define_message_handler(:spawn_application, :handle_spawn_application)
84:                 define_message_handler(:reload, :handle_reload)
85:         end

Public Instance methods

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

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:

[Source]

     # File lib/phusion_passenger/classic_rails/framework_spawner.rb, line 188
188:         def reload(app_group_name = nil)
189:                 connect do |channel|
190:                         if app_group_name.nil?
191:                                 channel.write("reload")
192:                         else
193:                                 channel.write("reload", app_group_name)
194:                         end
195:                 end
196:         rescue SystemCallError, IOError, SocketError
197:                 raise Error, "The framework spawner server exited unexpectedly: #{e}"
198:         end

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.

All options accepted by ApplicationSpawner.new and RequestHandler.new are accepted.

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:

[Source]

     # File lib/phusion_passenger/classic_rails/framework_spawner.rb, line 140
140:         def spawn_application(options = {})
141:                 app_root = options["app_root"]
142:                 options = sanitize_spawn_options(options)
143:                 options["app_root"] = app_root
144:                 # No need for the ApplicationSpawner to print exceptions. All
145:                 # exceptions raised by the ApplicationSpawner are sent back here,
146:                 # so we just need to decide here whether we want to print it.
147:                 print_exceptions = options["print_exceptions"]
148:                 options["print_exceptions"] = false
149:                 
150:                 begin
151:                         connect do |channel|
152:                                 channel.write("spawn_application", *options.to_a.flatten)
153:                                 result = channel.read
154:                                 if result.nil?
155:                                         raise IOError, "Connection closed"
156:                                 end
157:                                 if result[0] == 'exception'
158:                                         e = unmarshal_exception(channel.read_scalar)
159:                                         if print_exceptions && e.respond_to?(:child_exception) && e.child_exception
160:                                                 print_exception(self.class.to_s, e.child_exception)
161:                                         elsif print_exceptions
162:                                                 print_exception(self.class.to_s, e)
163:                                         end
164:                                         raise e
165:                                 else
166:                                         return AppProcess.read_from_channel(channel)
167:                                 end
168:                         end
169:                 rescue SystemCallError, IOError, SocketError => e
170:                         raise Error, "The framework spawner server exited unexpectedly: #{e}"
171:                 end
172:         end

Overrided from AbstractServer#start.

May raise these additional exceptions:

[Source]

     # File lib/phusion_passenger/classic_rails/framework_spawner.rb, line 92
 92:         def start
 93:                 super
 94:                 begin
 95:                         channel = MessageChannel.new(@owner_socket)
 96:                         result = channel.read
 97:                         if result.nil?
 98:                                 raise Error, "The framework spawner server exited unexpectedly."
 99:                         else
100:                                 status = result[0]
101:                         end
102:                         if status == 'exception'
103:                                 child_exception = unmarshal_exception(channel.read_scalar)
104:                                 stop
105:                                 message = "Could not load Ruby on Rails framework version #{@framework_version}: " <<
106:                                         "#{child_exception.class} (#{child_exception.message})"
107:                                 options = { :version => @framework_version }
108:                                 if @print_framework_loading_exceptions
109:                                         print_exception(self.class.to_s, child_exception)
110:                                 end
111:                                 raise FrameworkInitError.new(message, child_exception, options)
112:                         end
113:                 rescue IOError, SystemCallError, SocketError => e
114:                         stop if started?
115:                         raise Error, "The framework spawner server exited unexpectedly: #{e}"
116:                 rescue
117:                         stop if started?
118:                         raise
119:                 end
120:         end

[Validate]