Class: PhusionPassenger::Railz::FrameworkSpawner
- Inherits:
-
AbstractServer
- Object
- AbstractServer
- PhusionPassenger::Railz::FrameworkSpawner
- Includes:
- Utils
- Defined in:
- lib/phusion_passenger/railz/framework_spawner.rb
Overview
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.
Defined Under Namespace
Classes: Error
Constant Summary
Constants inherited from AbstractServer
AbstractServer::SERVER_TERMINATION_SIGNAL
Instance Attribute Summary
Attributes inherited from AbstractServer
#last_activity_time, #max_idle_time, #next_cleaning_time
Instance Method Summary collapse
-
#initialize(options = {}) ⇒ FrameworkSpawner
constructor
Creates a new instance of FrameworkSpawner.
-
#reload(app_root = nil) ⇒ Object
Remove the cached application instances at the given application root.
-
#spawn_application(app_root, options = {}) ⇒ Object
Spawn a RoR application using the Ruby on Rails framework version associated with this FrameworkSpawner.
-
#start ⇒ Object
Overrided from AbstractServer#start.
Methods inherited from AbstractServer
#server_pid, #start_synchronously, #started?, #stop
Constructor Details
#initialize(options = {}) ⇒ FrameworkSpawner
Creates a new instance of FrameworkSpawner.
Valid options are:
-
: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”. -
:print_framework_loading_exceptions
: Whether exceptions that have occurred while loading the Ruby on Rails framework should be printed to STDERR. The default is true.
It is not allowed to specify both version
and vendor
.
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.
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/phusion_passenger/railz/framework_spawner.rb', line 72 def initialize( = {}) if !.respond_to?(:'[]') raise ArgumentError, "The 'options' argument not seem to be an options hash" end @version = [:version] @vendor = [:vendor] if .has_key?(:print_framework_loading_exceptions) @print_framework_loading_exceptions = [:print_framework_loading_exceptions] else @print_framework_loading_exceptions = true end if !@version && !@vendor raise ArgumentError, "Either the 'version' or the 'vendor' option must specified" elsif @version && @vendor raise ArgumentError, "It is not allowed to specify both the 'version' and the 'vendor' options" end super() self.max_idle_time = DEFAULT_FRAMEWORK_SPAWNER_MAX_IDLE_TIME (:spawn_application, :handle_spawn_application) (:reload, :handle_reload) end |
Instance Method Details
#reload(app_root = nil) ⇒ Object
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:
-
ArgumentError:
app_root
doesn’t appear to be a valid Ruby on Rails application root. -
FrameworkSpawner::Error: The FrameworkSpawner server exited unexpectedly.
204 205 206 207 208 209 210 211 212 |
# File 'lib/phusion_passenger/railz/framework_spawner.rb', line 204 def reload(app_root = nil) if app_root.nil? server.write("reload") else server.write("reload", app_root) end rescue SystemCallError, IOError, SocketError raise Error, "The framework spawner server exited unexpectedly" end |
#spawn_application(app_root, options = {}) ⇒ Object
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:
-
Restart this FrameworkSpawner by calling AbstractServer#stop, then AbstractServer#start.
-
Reload the application by calling reload with the correct app_root argument.
Raises:
-
AbstractServer::ServerNotStarted: The FrameworkSpawner server hasn’t already been started.
-
InvalidPath:
app_root
doesn’t appear to be a valid Ruby on Rails application root. -
AppInitError: The application raised an exception or called exit() during startup.
-
ApplicationSpawner::Error: The ApplicationSpawner server exited unexpectedly.
-
FrameworkSpawner::Error: The FrameworkSpawner server exited unexpectedly.
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/phusion_passenger/railz/framework_spawner.rb', line 150 def spawn_application(app_root, = {}) assert_valid_app_root(app_root) = () ["app_root"] = app_root # No need for the ApplicationSpawner to print exceptions. All # exceptions raised by the ApplicationSpawner are sent back here, # so we just need to decide here whether we want to print it. print_exceptions = ["print_exceptions"] ["print_exceptions"] = false begin server.write("spawn_application", *.to_a.flatten) result = server.read if result.nil? raise IOError, "Connection closed" end if result[0] == 'exception' e = unmarshal_exception(server.read_scalar) if print_exceptions && e.respond_to?(:child_exception) && e.child_exception print_exception(self.class.to_s, e.child_exception) elsif print_exceptions print_exception(self.class.to_s, e) end raise e else pid, listen_socket_name, socket_type = server.read if pid.nil? raise IOError, "Connection closed" end owner_pipe = server.recv_io return Application.new(app_root, pid, listen_socket_name, socket_type, owner_pipe) end rescue SystemCallError, IOError, SocketError => e raise Error, "The framework spawner server exited unexpectedly" end end |
#start ⇒ Object
Overrided from AbstractServer#start.
May raise these additional exceptions:
-
FrameworkInitError: An error occurred while loading the specified Ruby on Rails framework.
-
FrameworkSpawner::Error: The FrameworkSpawner server exited unexpectedly.
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/phusion_passenger/railz/framework_spawner.rb', line 100 def start super begin result = server.read if result.nil? raise Error, "The framework spawner server exited unexpectedly." else status = result[0] end if status == 'exception' child_exception = unmarshal_exception(server.read_scalar) stop if @version = "Could not load Ruby on Rails framework version #{@version}: " << "#{child_exception.class} (#{child_exception.})" else = "Could not load Ruby on Rails framework at '#{@vendor}': " << "#{child_exception.class} (#{child_exception.})" end = { :vendor => @vendor, :version => @version } if @print_framework_loading_exceptions print_exception(self.class.to_s, child_exception) end raise FrameworkInitError.new(, child_exception, ) end rescue IOError, SystemCallError, SocketError stop raise Error, "The framework spawner server exited unexpectedly" end end |