Class PhusionPassenger::AppProcess
In: lib/phusion_passenger/app_process.rb
Parent: Object

Contains various information about an application process.

Methods

Attributes

app_root  [R]  The root directory of this application process.
owner_pipe  [R]  The owner pipe of the application instance (an IO object). Please see RequestHandler for a description of the owner pipe.
pid  [R]  This process‘s PID.
server_sockets  [R]  A hash containing all server sockets that this application process listens on. The hash is in the form of:
  {
     name1 => [socket_address1, socket_type1],
     name2 => [socket_address2, socket_type2],
     ...
  }

name is a Symbol. socket_addressx is the address of the socket and +socket_type1+ is the socket‘s type (either ‘unix’ or ‘tcp’). There‘s guaranteed to be at least one server socket, namely one with the name +:main+.

Public Class methods

  • Returns the Ruby on Rails version that the application requires.
  • Returns :vendor if the application has a vendored Rails.
  • Returns nil if the application doesn‘t specify a particular version.

Raises VersionNotFound if the required Rails version is not installed.

[Source]

    # File lib/phusion_passenger/app_process.rb, line 59
59:         def self.detect_framework_version(app_root)
60:                 if File.directory?("#{app_root}/vendor/rails/railties")
61:                         # NOTE: We must check for 'rails/railties' and not just 'rails'.
62:                         # Typo's vendor directory contains an empty 'rails' directory.
63:                         return :vendor
64:                 end
65:                 
66:                 environment_rb = File.read("#{app_root}/config/environment.rb")
67:                 environment_rb =~ /^[^#]*RAILS_GEM_VERSION\s*=\s*["']([!~<>=]*\s*[\d.]+)["']/
68:                 gem_version_spec = $1
69:                 if gem_version_spec.nil?
70:                         return nil
71:                 end
72:                 
73:                 search_results = Gem.cache.search(Gem::Dependency.new('rails', gem_version_spec), true)
74:                 found_version = search_results.map do |x|
75:                         x.version.version
76:                 end.sort.last
77:                 if found_version.nil?
78:                         # If this error was reported before, then the cache might be out of
79:                         # date because the Rails version may have been installed now.
80:                         # So we reload the RubyGems cache and try again.
81:                         Gem.clear_paths
82:                         search_results = Gem.cache.search(Gem::Dependency.new('rails', gem_version_spec), true)
83:                         found_version = search_results.map do |x|
84:                                 x.version.version
85:                         end.sort.last
86:                 end
87:                 
88:                 if found_version.nil?
89:                         raise VersionNotFound.new("There is no Ruby on Rails version " <<
90:                                 "installed that matches version \"#{gem_version_spec}\"",
91:                                 gem_version_spec)
92:                 else
93:                         return found_version
94:                 end
95:         end

Creates a new AppProcess instance. The parameters correspond with the attributes of the same names. No exceptions will be thrown.

[Source]

     # File lib/phusion_passenger/app_process.rb, line 137
137:         def initialize(app_root, pid, owner_pipe, server_sockets)
138:                 @app_root   = app_root
139:                 @pid        = pid
140:                 @owner_pipe = owner_pipe
141:                 
142:                 # We copy the values like this so one can directly pass
143:                 # AbstractRequestHandler#server_sockets as arguments
144:                 # without having AppProcess store references to the socket
145:                 # IO objects.
146:                 @server_sockets = {}
147:                 server_sockets.each_pair do |name, value|
148:                         @server_sockets[name] = [value[0], value[1]]
149:                 end
150:         end

Construct an AppProcess by reading information from the given MessageChannel. The other side of the channel must be writing AppProcess information using AppProcess#write_to_channel.

Might raise SystemCallError, IOError or SocketError.

[Source]

     # File lib/phusion_passenger/app_process.rb, line 102
102:         def self.read_from_channel(channel)
103:                 app_root, pid, n_server_sockets = channel.read
104:                 if app_root.nil?
105:                         raise IOError, "Connection closed"
106:                 end
107:                 
108:                 server_sockets = {}
109:                 n_server_sockets.to_i.times do
110:                         message = channel.read
111:                         if message.nil?
112:                                 raise IOError, "Connection closed"
113:                         end
114:                         name = message.shift
115:                         server_sockets[name.to_sym] = message
116:                 end
117:                 
118:                 owner_pipe = channel.recv_io
119:                 
120:                 return new(app_root, pid.to_i, owner_pipe, server_sockets)
121:         end

Public Instance methods

Close the connection with the application process. If there are no other processes that have connections to this application process, then it will shutdown as soon as possible.

See also AbstractRequestHandler#owner_pipe.

[Source]

     # File lib/phusion_passenger/app_process.rb, line 157
157:         def close
158:                 @owner_pipe.close rescue nil
159:         end

Write this AppProcess‘s information over the given MessageChannel. The other side must read the information using AppProces.read_from_channel.

Might raise SystemCallError, IOError or SocketError.

[Source]

     # File lib/phusion_passenger/app_process.rb, line 127
127:         def write_to_channel(channel)
128:                 channel.write(@app_root, @pid, @server_sockets.size)
129:                 @server_sockets.each_pair do |name, value|
130:                         channel.write(name.to_s, *value)
131:                 end
132:                 channel.send_io(@owner_pipe)
133:         end

[Validate]