passenger 2.2.7 → 2.2.8
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of passenger might be problematic. Click here for more details.
- data/NEWS +40 -0
- data/Rakefile +1 -1
- data/bin/passenger-install-apache2-module +1 -0
- data/bin/passenger-install-nginx-module +2 -0
- data/doc/Architectural overview.html +173 -138
- data/doc/Security of user switching support.html +147 -109
- data/doc/Users guide Apache.html +4 -43
- data/doc/Users guide Nginx.html +4 -43
- data/doc/cxxapi/Bucket_8h-source.html +1 -1
- data/doc/cxxapi/Configuration_8h-source.html +1 -1
- data/doc/cxxapi/DirectoryMapper_8h-source.html +1 -1
- data/doc/cxxapi/Hooks_8h-source.html +1 -1
- data/doc/cxxapi/annotated.html +1 -1
- data/doc/cxxapi/classHooks-members.html +1 -1
- data/doc/cxxapi/classHooks.html +1 -1
- data/doc/cxxapi/classPassenger_1_1DirectoryMapper-members.html +1 -1
- data/doc/cxxapi/classPassenger_1_1DirectoryMapper.html +1 -1
- data/doc/cxxapi/classes.html +1 -1
- data/doc/cxxapi/definitions_8h-source.html +1 -1
- data/doc/cxxapi/files.html +1 -1
- data/doc/cxxapi/functions.html +1 -1
- data/doc/cxxapi/functions_func.html +1 -1
- data/doc/cxxapi/graph_legend.html +1 -1
- data/doc/cxxapi/group__Configuration.html +1 -1
- data/doc/cxxapi/group__Core.html +1 -1
- data/doc/cxxapi/group__Hooks.html +1 -1
- data/doc/cxxapi/group__Support.html +1 -1
- data/doc/cxxapi/main.html +1 -1
- data/doc/cxxapi/modules.html +1 -1
- data/doc/rdoc/classes/GC.html +4 -4
- data/doc/rdoc/classes/PhusionPassenger.html +2 -1
- data/doc/rdoc/classes/PhusionPassenger/AbstractInstaller.html +8 -8
- data/doc/rdoc/classes/PhusionPassenger/AbstractRequestHandler.html +26 -26
- data/doc/rdoc/classes/PhusionPassenger/AbstractServer.html +98 -98
- data/doc/rdoc/classes/PhusionPassenger/AbstractServerCollection.html +61 -61
- data/doc/rdoc/classes/PhusionPassenger/AppInitError.html +4 -4
- data/doc/rdoc/classes/PhusionPassenger/Application.html +14 -14
- data/doc/rdoc/classes/PhusionPassenger/ConsoleTextTemplate.html +12 -12
- data/doc/rdoc/classes/PhusionPassenger/FrameworkInitError.html +4 -4
- data/doc/rdoc/classes/PhusionPassenger/HTMLTemplate.html +12 -12
- data/doc/rdoc/classes/PhusionPassenger/InitializationError.html +5 -5
- data/doc/rdoc/classes/PhusionPassenger/MessageChannel.html +42 -42
- data/doc/rdoc/classes/PhusionPassenger/Rack/ApplicationSpawner.html +33 -33
- data/doc/rdoc/classes/PhusionPassenger/Rack/RequestHandler.html +59 -59
- data/doc/rdoc/classes/PhusionPassenger/Railz/ApplicationSpawner.html +3 -3
- data/doc/rdoc/classes/PhusionPassenger/Railz/FrameworkSpawner.html +7 -7
- data/doc/rdoc/classes/PhusionPassenger/SpawnManager.html +23 -23
- data/doc/rdoc/classes/PhusionPassenger/UnknownError.html +4 -4
- data/doc/rdoc/classes/PhusionPassenger/Utils.html +2 -0
- data/doc/rdoc/classes/PhusionPassenger/Utils/PseudoIO.html +16 -16
- data/doc/rdoc/classes/PhusionPassenger/VersionNotFound.html +4 -4
- data/doc/rdoc/classes/PlatformInfo.html +1 -1
- data/doc/rdoc/classes/Signal.html +23 -15
- data/doc/rdoc/created.rid +1 -1
- data/doc/rdoc/files/DEVELOPERS_TXT.html +1 -1
- data/doc/rdoc/files/README.html +1 -1
- data/doc/rdoc/files/ext/phusion_passenger/native_support_c.html +1 -1
- data/doc/rdoc/files/lib/phusion_passenger/abstract_installer_rb.html +1 -1
- data/doc/rdoc/files/lib/phusion_passenger/abstract_request_handler_rb.html +1 -1
- data/doc/rdoc/files/lib/phusion_passenger/abstract_server_collection_rb.html +1 -1
- data/doc/rdoc/files/lib/phusion_passenger/abstract_server_rb.html +1 -1
- data/doc/rdoc/files/lib/phusion_passenger/admin_tools/control_process_rb.html +1 -1
- data/doc/rdoc/files/lib/phusion_passenger/admin_tools_rb.html +1 -1
- data/doc/rdoc/files/lib/phusion_passenger/application_rb.html +1 -1
- data/doc/rdoc/files/lib/phusion_passenger/console_text_template_rb.html +1 -1
- data/doc/rdoc/files/lib/phusion_passenger/constants_rb.html +1 -1
- data/doc/rdoc/files/lib/phusion_passenger/dependencies_rb.html +1 -1
- data/doc/rdoc/files/lib/phusion_passenger/events_rb.html +1 -1
- data/doc/rdoc/files/lib/phusion_passenger/exceptions_rb.html +1 -1
- data/doc/rdoc/files/lib/phusion_passenger/html_template_rb.html +1 -1
- data/doc/rdoc/files/lib/phusion_passenger/message_channel_rb.html +1 -1
- data/doc/rdoc/files/lib/phusion_passenger/packaging_rb.html +1 -1
- data/doc/rdoc/files/lib/phusion_passenger/platform_info_rb.html +1 -1
- data/doc/rdoc/files/lib/phusion_passenger/rack/application_spawner_rb.html +2 -2
- data/doc/rdoc/files/lib/phusion_passenger/rack/request_handler_rb.html +2 -2
- data/doc/rdoc/files/lib/phusion_passenger/railz/application_spawner_rb.html +1 -1
- data/doc/rdoc/files/lib/phusion_passenger/railz/cgi_fixed_rb.html +1 -1
- data/doc/rdoc/files/lib/phusion_passenger/railz/framework_spawner_rb.html +1 -1
- data/doc/rdoc/files/lib/phusion_passenger/railz/request_handler_rb.html +1 -1
- data/doc/rdoc/files/lib/phusion_passenger/simple_benchmarking_rb.html +1 -1
- data/doc/rdoc/files/lib/phusion_passenger/spawn_manager_rb.html +1 -1
- data/doc/rdoc/files/lib/phusion_passenger/utils_rb.html +9 -9
- data/doc/rdoc/files/lib/phusion_passenger/wsgi/application_spawner_rb.html +1 -1
- data/doc/rdoc/files/misc/rake/extensions_rb.html +1 -1
- data/doc/rdoc/fr_class_index.html +2 -0
- data/doc/rdoc/fr_file_index.html +1 -0
- data/doc/rdoc/fr_method_index.html +79 -72
- data/ext/apache2/Hooks.cpp +4 -2
- data/ext/common/StandardApplicationPool.h +4 -2
- data/ext/common/Version.h +1 -1
- data/ext/nginx/Configuration.c +1 -1
- data/ext/oxt/system_calls.cpp +11 -0
- data/ext/oxt/system_calls.hpp +2 -1
- data/ext/oxt/thread.hpp +97 -1
- data/lib/phusion_passenger/constants.rb +1 -1
- data/lib/phusion_passenger/dependencies.rb +32 -0
- data/lib/phusion_passenger/platform_info.rb +1 -1
- data/lib/phusion_passenger/rack/application_spawner.rb +4 -4
- data/lib/phusion_passenger/rack/request_handler.rb +2 -5
- data/lib/phusion_passenger/railz/application_spawner.rb +13 -2
- data/lib/phusion_passenger/utils.rb +12 -4
- data/{vendor/rack-1.0.0-git/lib/rack → lib/phusion_passenger/utils}/rewindable_input.rb +19 -3
- data/test/ApplicationPoolTest.cpp +1 -1
- metadata +13 -59
- data/vendor/README +0 -13
- data/vendor/README_FOR_PACKAGERS +0 -1
- data/vendor/rack-1.0.0-git/COPYING +0 -18
- data/vendor/rack-1.0.0-git/KNOWN-ISSUES +0 -18
- data/vendor/rack-1.0.0-git/README +0 -353
- data/vendor/rack-1.0.0-git/Rakefile +0 -164
- data/vendor/rack-1.0.0-git/lib/rack.rb +0 -90
- data/vendor/rack-1.0.0-git/lib/rack/adapter/camping.rb +0 -22
- data/vendor/rack-1.0.0-git/lib/rack/auth/abstract/handler.rb +0 -37
- data/vendor/rack-1.0.0-git/lib/rack/auth/abstract/request.rb +0 -37
- data/vendor/rack-1.0.0-git/lib/rack/auth/basic.rb +0 -58
- data/vendor/rack-1.0.0-git/lib/rack/auth/digest/md5.rb +0 -124
- data/vendor/rack-1.0.0-git/lib/rack/auth/digest/nonce.rb +0 -51
- data/vendor/rack-1.0.0-git/lib/rack/auth/digest/params.rb +0 -55
- data/vendor/rack-1.0.0-git/lib/rack/auth/digest/request.rb +0 -40
- data/vendor/rack-1.0.0-git/lib/rack/auth/openid.rb +0 -487
- data/vendor/rack-1.0.0-git/lib/rack/builder.rb +0 -63
- data/vendor/rack-1.0.0-git/lib/rack/cascade.rb +0 -41
- data/vendor/rack-1.0.0-git/lib/rack/chunked.rb +0 -49
- data/vendor/rack-1.0.0-git/lib/rack/commonlogger.rb +0 -52
- data/vendor/rack-1.0.0-git/lib/rack/conditionalget.rb +0 -47
- data/vendor/rack-1.0.0-git/lib/rack/content_length.rb +0 -29
- data/vendor/rack-1.0.0-git/lib/rack/content_type.rb +0 -23
- data/vendor/rack-1.0.0-git/lib/rack/deflater.rb +0 -96
- data/vendor/rack-1.0.0-git/lib/rack/directory.rb +0 -153
- data/vendor/rack-1.0.0-git/lib/rack/file.rb +0 -88
- data/vendor/rack-1.0.0-git/lib/rack/handler.rb +0 -69
- data/vendor/rack-1.0.0-git/lib/rack/handler/cgi.rb +0 -61
- data/vendor/rack-1.0.0-git/lib/rack/handler/evented_mongrel.rb +0 -8
- data/vendor/rack-1.0.0-git/lib/rack/handler/fastcgi.rb +0 -88
- data/vendor/rack-1.0.0-git/lib/rack/handler/lsws.rb +0 -55
- data/vendor/rack-1.0.0-git/lib/rack/handler/mongrel.rb +0 -84
- data/vendor/rack-1.0.0-git/lib/rack/handler/scgi.rb +0 -59
- data/vendor/rack-1.0.0-git/lib/rack/handler/swiftiplied_mongrel.rb +0 -8
- data/vendor/rack-1.0.0-git/lib/rack/handler/thin.rb +0 -18
- data/vendor/rack-1.0.0-git/lib/rack/handler/webrick.rb +0 -67
- data/vendor/rack-1.0.0-git/lib/rack/head.rb +0 -19
- data/vendor/rack-1.0.0-git/lib/rack/lint.rb +0 -537
- data/vendor/rack-1.0.0-git/lib/rack/lobster.rb +0 -65
- data/vendor/rack-1.0.0-git/lib/rack/lock.rb +0 -16
- data/vendor/rack-1.0.0-git/lib/rack/methodoverride.rb +0 -27
- data/vendor/rack-1.0.0-git/lib/rack/mime.rb +0 -204
- data/vendor/rack-1.0.0-git/lib/rack/mock.rb +0 -184
- data/vendor/rack-1.0.0-git/lib/rack/recursive.rb +0 -57
- data/vendor/rack-1.0.0-git/lib/rack/reloader.rb +0 -106
- data/vendor/rack-1.0.0-git/lib/rack/request.rb +0 -248
- data/vendor/rack-1.0.0-git/lib/rack/response.rb +0 -183
- data/vendor/rack-1.0.0-git/lib/rack/session/abstract/id.rb +0 -142
- data/vendor/rack-1.0.0-git/lib/rack/session/cookie.rb +0 -91
- data/vendor/rack-1.0.0-git/lib/rack/session/memcache.rb +0 -109
- data/vendor/rack-1.0.0-git/lib/rack/session/pool.rb +0 -100
- data/vendor/rack-1.0.0-git/lib/rack/showexceptions.rb +0 -349
- data/vendor/rack-1.0.0-git/lib/rack/showstatus.rb +0 -106
- data/vendor/rack-1.0.0-git/lib/rack/static.rb +0 -38
- data/vendor/rack-1.0.0-git/lib/rack/urlmap.rb +0 -55
- data/vendor/rack-1.0.0-git/lib/rack/utils.rb +0 -522
data/NEWS
CHANGED
@@ -1,3 +1,43 @@
|
|
1
|
+
Release 2.2.8
|
2
|
+
-------------
|
3
|
+
|
4
|
+
* [Nginx] Fixed some signal handling problems.
|
5
|
+
Restarting Nginx on OS X with SIGHUP can sometimes take a long time or
|
6
|
+
even fail completely. This is because of some signal handling problems,
|
7
|
+
which have now been fixed.
|
8
|
+
* [Nginx] Added OpenSSL as dependency.
|
9
|
+
OpenSSL is required in order to install Nginx, but this was not checked
|
10
|
+
by passenger-install-nginx-module. As a result,
|
11
|
+
passenger-install-nginx-module fails on e.g. out-of-the-box Ubuntu
|
12
|
+
installations until the user manually installs OpenSSL. Issue #422.
|
13
|
+
* [Nginx] Fixed support for internal redirects and subrequests.
|
14
|
+
It is now possible to, for example, point X-Accel-Redirects to Phusion
|
15
|
+
Passenger-served URLs. Patch contributed by W. Andrew Loe III: issue #433.
|
16
|
+
* [Apache] Fixed a GnuTLS compatibility issue.
|
17
|
+
mod_gnutls can cause Phusion Passenger to crash because of an unchecked
|
18
|
+
NULL pointer. This problem has now been fixed: issue #391.
|
19
|
+
* Fixed thread creation issue on Intel Itanium platforms.
|
20
|
+
This fixes issue #427.
|
21
|
+
* Fixed compilation problems on Linux running on the Renesas SH4 CPU.
|
22
|
+
Patch contributed by iwamatsu: issue #428.
|
23
|
+
* The Rack library has been unvendored.
|
24
|
+
The original reason for vendoring was to work around broken Rails
|
25
|
+
applications that explicitly specify Rack as a gem dependency. We've
|
26
|
+
found a better workaround that does not require vendoring Rack.
|
27
|
+
This also fixes a compatibility problem with Rails 3, because Rails
|
28
|
+
3 depends on a newer Rack version than the one we had vendored.
|
29
|
+
Issue #432.
|
30
|
+
* Fixed compatibility with Ruby 1.9.1 patchlevel >= 152
|
31
|
+
Ruby 1.9.1 patchlevel >= 152 has a bug in its tempfile library. If you've
|
32
|
+
seen an error message along the lines of
|
33
|
+
|
34
|
+
*** Exception IOError in Passenger RequestHandler (closed stream)
|
35
|
+
|
36
|
+
then this is a Ruby bug at work. This bug has been fixed in Ruby 1.9.2,
|
37
|
+
but Ruby 1.9.1 still contains this bug. We've added a workaround so that
|
38
|
+
the bug is not triggered with this Ruby version. Issue #432.
|
39
|
+
|
40
|
+
|
1
41
|
Release 2.2.7
|
2
42
|
-------------
|
3
43
|
|
data/Rakefile
CHANGED
@@ -656,6 +656,7 @@ spec = Gem::Specification.new do |s|
|
|
656
656
|
s.require_paths = ["lib", "ext"]
|
657
657
|
s.add_dependency 'rake', '>= 0.8.1'
|
658
658
|
s.add_dependency 'fastthread', '>= 1.0.1'
|
659
|
+
s.add_dependency 'rack'
|
659
660
|
s.extensions << 'ext/phusion_passenger/extconf.rb'
|
660
661
|
s.files = FileList[
|
661
662
|
'Rakefile',
|
@@ -699,7 +700,6 @@ spec = Gem::Specification.new do |s|
|
|
699
700
|
'benchmark/*.{cpp,rb}',
|
700
701
|
'misc/*',
|
701
702
|
'misc/*/*',
|
702
|
-
'vendor/**/*',
|
703
703
|
'test/*.{rb,cpp,example}',
|
704
704
|
'test/support/*.{cpp,h,rb}',
|
705
705
|
'test/oxt/*.cpp',
|
@@ -3,7 +3,8 @@
|
|
3
3
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
4
4
|
<head>
|
5
5
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
6
|
-
<meta name="generator" content="AsciiDoc 8.2
|
6
|
+
<meta name="generator" content="AsciiDoc 8.4.2" />
|
7
|
+
<title>Passenger architectural overview</title>
|
7
8
|
<style type="text/css">
|
8
9
|
/* Debug borders */
|
9
10
|
p, li, dt, dd, div, pre, h1, h2, h3, h4, h5, h6 {
|
@@ -26,10 +27,12 @@ a:visited {
|
|
26
27
|
|
27
28
|
em {
|
28
29
|
font-style: italic;
|
30
|
+
color: navy;
|
29
31
|
}
|
30
32
|
|
31
33
|
strong {
|
32
34
|
font-weight: bold;
|
35
|
+
color: #083194;
|
33
36
|
}
|
34
37
|
|
35
38
|
tt {
|
@@ -71,6 +74,10 @@ p {
|
|
71
74
|
margin-bottom: 0.5em;
|
72
75
|
}
|
73
76
|
|
77
|
+
ul, ol, li > p {
|
78
|
+
margin-top: 0;
|
79
|
+
}
|
80
|
+
|
74
81
|
pre {
|
75
82
|
padding: 0;
|
76
83
|
margin: 0;
|
@@ -104,11 +111,13 @@ div#footer-badges {
|
|
104
111
|
padding-bottom: 0.5em;
|
105
112
|
}
|
106
113
|
|
107
|
-
div#preamble
|
114
|
+
div#preamble {
|
115
|
+
margin-top: 1.5em;
|
116
|
+
margin-bottom: 1.5em;
|
117
|
+
}
|
108
118
|
div.tableblock, div.imageblock, div.exampleblock, div.verseblock,
|
109
119
|
div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
|
110
120
|
div.admonitionblock {
|
111
|
-
margin-right: 10%;
|
112
121
|
margin-top: 1.5em;
|
113
122
|
margin-bottom: 1.5em;
|
114
123
|
}
|
@@ -123,6 +132,7 @@ div.content { /* Block element content. */
|
|
123
132
|
|
124
133
|
/* Block element titles. */
|
125
134
|
div.title, caption.title {
|
135
|
+
color: #527bbd;
|
126
136
|
font-family: sans-serif;
|
127
137
|
font-weight: bold;
|
128
138
|
text-align: left;
|
@@ -149,22 +159,33 @@ div.sidebarblock > div.content {
|
|
149
159
|
padding: 0.5em;
|
150
160
|
}
|
151
161
|
|
152
|
-
div.listingblock {
|
153
|
-
margin-right: 0%;
|
154
|
-
}
|
155
162
|
div.listingblock > div.content {
|
156
163
|
border: 1px solid silver;
|
157
164
|
background: #f4f4f4;
|
158
165
|
padding: 0.5em;
|
159
166
|
}
|
160
167
|
|
161
|
-
div.quoteblock
|
168
|
+
div.quoteblock {
|
162
169
|
padding-left: 2.0em;
|
170
|
+
margin-right: 10%;
|
163
171
|
}
|
164
|
-
|
165
|
-
|
172
|
+
div.quoteblock > div.attribution {
|
173
|
+
padding-top: 0.5em;
|
166
174
|
text-align: right;
|
167
175
|
}
|
176
|
+
|
177
|
+
div.verseblock {
|
178
|
+
padding-left: 2.0em;
|
179
|
+
margin-right: 10%;
|
180
|
+
}
|
181
|
+
div.verseblock > div.content {
|
182
|
+
white-space: pre;
|
183
|
+
}
|
184
|
+
div.verseblock > div.attribution {
|
185
|
+
padding-top: 0.75em;
|
186
|
+
text-align: left;
|
187
|
+
}
|
188
|
+
/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
|
168
189
|
div.verseblock + div.attribution {
|
169
190
|
text-align: left;
|
170
191
|
}
|
@@ -187,10 +208,6 @@ div.exampleblock > div.content {
|
|
187
208
|
padding: 0.5em;
|
188
209
|
}
|
189
210
|
|
190
|
-
div.verseblock div.content {
|
191
|
-
white-space: pre;
|
192
|
-
}
|
193
|
-
|
194
211
|
div.imageblock div.content { padding-left: 0; }
|
195
212
|
div.imageblock img { border: 1px solid silver; }
|
196
213
|
span.image img { border-style: none; }
|
@@ -202,18 +219,38 @@ dl {
|
|
202
219
|
dt {
|
203
220
|
margin-top: 0.5em;
|
204
221
|
margin-bottom: 0;
|
205
|
-
font-style:
|
222
|
+
font-style: normal;
|
223
|
+
color: navy;
|
206
224
|
}
|
207
225
|
dd > *:first-child {
|
208
|
-
margin-top: 0;
|
226
|
+
margin-top: 0.1em;
|
209
227
|
}
|
210
228
|
|
211
229
|
ul, ol {
|
212
230
|
list-style-position: outside;
|
213
231
|
}
|
214
|
-
|
232
|
+
ol.arabic {
|
233
|
+
list-style-type: decimal;
|
234
|
+
}
|
235
|
+
ol.loweralpha {
|
215
236
|
list-style-type: lower-alpha;
|
216
237
|
}
|
238
|
+
ol.upperalpha {
|
239
|
+
list-style-type: upper-alpha;
|
240
|
+
}
|
241
|
+
ol.lowerroman {
|
242
|
+
list-style-type: lower-roman;
|
243
|
+
}
|
244
|
+
ol.upperroman {
|
245
|
+
list-style-type: upper-roman;
|
246
|
+
}
|
247
|
+
|
248
|
+
div.compact ul, div.compact ol,
|
249
|
+
div.compact p, div.compact p,
|
250
|
+
div.compact div, div.compact div {
|
251
|
+
margin-top: 0.1em;
|
252
|
+
margin-bottom: 0.1em;
|
253
|
+
}
|
217
254
|
|
218
255
|
div.tableblock > table {
|
219
256
|
border: 3px solid #527bbd;
|
@@ -225,22 +262,53 @@ thead {
|
|
225
262
|
tfoot {
|
226
263
|
font-weight: bold;
|
227
264
|
}
|
265
|
+
td > div.verse {
|
266
|
+
white-space: pre;
|
267
|
+
}
|
268
|
+
p.table {
|
269
|
+
margin-top: 0;
|
270
|
+
}
|
271
|
+
/* Because the table frame attribute is overriden by CSS in most browsers. */
|
272
|
+
div.tableblock > table[frame="void"] {
|
273
|
+
border-style: none;
|
274
|
+
}
|
275
|
+
div.tableblock > table[frame="hsides"] {
|
276
|
+
border-left-style: none;
|
277
|
+
border-right-style: none;
|
278
|
+
}
|
279
|
+
div.tableblock > table[frame="vsides"] {
|
280
|
+
border-top-style: none;
|
281
|
+
border-bottom-style: none;
|
282
|
+
}
|
283
|
+
|
228
284
|
|
229
|
-
div.
|
285
|
+
div.hdlist {
|
230
286
|
margin-top: 0.8em;
|
231
287
|
margin-bottom: 0.8em;
|
232
288
|
}
|
233
|
-
div.
|
234
|
-
padding-bottom:
|
289
|
+
div.hdlist tr {
|
290
|
+
padding-bottom: 15px;
|
235
291
|
}
|
236
|
-
td.
|
292
|
+
dt.hdlist1.strong, td.hdlist1.strong {
|
293
|
+
font-weight: bold;
|
294
|
+
}
|
295
|
+
td.hdlist1 {
|
237
296
|
vertical-align: top;
|
238
|
-
font-style:
|
297
|
+
font-style: normal;
|
239
298
|
padding-right: 0.8em;
|
299
|
+
color: navy;
|
240
300
|
}
|
241
|
-
td.
|
301
|
+
td.hdlist2 {
|
242
302
|
vertical-align: top;
|
243
303
|
}
|
304
|
+
div.hdlist.compact tr {
|
305
|
+
margin: 0;
|
306
|
+
padding-bottom: 0;
|
307
|
+
}
|
308
|
+
|
309
|
+
.comment {
|
310
|
+
background: yellow;
|
311
|
+
}
|
244
312
|
|
245
313
|
@media print {
|
246
314
|
div#footer-badges { display: none; }
|
@@ -271,37 +339,6 @@ div.toclevel4 {
|
|
271
339
|
margin-left: 6em;
|
272
340
|
font-size: 0.9em;
|
273
341
|
}
|
274
|
-
/* Workarounds for IE6's broken and incomplete CSS2. */
|
275
|
-
|
276
|
-
div.sidebar-content {
|
277
|
-
background: #ffffee;
|
278
|
-
border: 1px solid silver;
|
279
|
-
padding: 0.5em;
|
280
|
-
}
|
281
|
-
div.sidebar-title, div.image-title {
|
282
|
-
font-family: sans-serif;
|
283
|
-
font-weight: bold;
|
284
|
-
margin-top: 0.0em;
|
285
|
-
margin-bottom: 0.5em;
|
286
|
-
}
|
287
|
-
|
288
|
-
div.listingblock div.content {
|
289
|
-
border: 1px solid silver;
|
290
|
-
background: #f4f4f4;
|
291
|
-
padding: 0.5em;
|
292
|
-
}
|
293
|
-
|
294
|
-
div.quoteblock-content {
|
295
|
-
padding-left: 2.0em;
|
296
|
-
}
|
297
|
-
|
298
|
-
div.exampleblock-content {
|
299
|
-
border-left: 2px solid silver;
|
300
|
-
padding-left: 0.5em;
|
301
|
-
}
|
302
|
-
|
303
|
-
/* IE6 sets dynamically generated links as visited. */
|
304
|
-
div#toc a:visited { color: blue; }
|
305
342
|
</style>
|
306
343
|
<script type="text/javascript">
|
307
344
|
/*<![CDATA[*/
|
@@ -372,10 +409,11 @@ function generateToc(toclevels) {
|
|
372
409
|
div.className = "toclevel" + entry.toclevel;
|
373
410
|
toc.appendChild(div);
|
374
411
|
}
|
412
|
+
if (entries.length == 0)
|
413
|
+
document.getElementById("header").removeChild(toc);
|
375
414
|
}
|
376
415
|
/*]]>*/
|
377
416
|
</script>
|
378
|
-
<title>Passenger architectural overview</title>
|
379
417
|
</head>
|
380
418
|
<body>
|
381
419
|
<div id="header">
|
@@ -387,30 +425,30 @@ function generateToc(toclevels) {
|
|
387
425
|
</div>
|
388
426
|
<div id="preamble">
|
389
427
|
<div class="sectionbody">
|
390
|
-
<div class="
|
428
|
+
<div class="paragraph"><p>This document describes Passenger’s architure in a global way. The purpose of
|
391
429
|
this document is to lower the barrier to entry for new contributors, as well
|
392
430
|
as to explain (some of the) design choices that we have made.</p></div>
|
393
|
-
<div class="
|
431
|
+
<div class="paragraph"><p>Or it can be a fun read for people who just want to know how Passenger works.</p></div>
|
394
432
|
</div>
|
395
433
|
</div>
|
396
434
|
<h2 id="_about_the_involved_technologies">1. About the involved technologies</h2>
|
397
435
|
<div class="sectionbody">
|
398
|
-
<h3 id="typical_web_applications">1.1. Typical web applications</h3
|
399
|
-
<div class="
|
436
|
+
<h3 id="typical_web_applications">1.1. Typical web applications</h3>
|
437
|
+
<div class="paragraph"><p>Before we describe Passenger, it is important to understand how typical web
|
400
438
|
applications work, from the point of view of someone who wants to connect the
|
401
439
|
application to a web server.</p></div>
|
402
|
-
<div class="
|
440
|
+
<div class="paragraph"><p>A typical, isolated, web application accepts an HTTP request from some I/O
|
403
441
|
channel, processes it internally, and outputs an HTTP response, which is sent
|
404
442
|
back to the client. This is done in a loop, until the application is commanded
|
405
443
|
to exit. This does not necessarily mean that the web application speaks HTTP
|
406
444
|
directly: it just means that the web application accepts some kind of
|
407
445
|
representation of an HTTP request.</p></div>
|
408
|
-
<div class="
|
446
|
+
<div class="paragraph"><p><span class="image">
|
409
447
|
<img src="images/typical_isolated_web_application.png" alt="Architecture of a typical web application in isolation" title="Architecture of a typical web application in isolation" />
|
410
448
|
</span></p></div>
|
411
|
-
<div class="
|
449
|
+
<div class="paragraph"><p>Few web applications are accessible directly by HTTP clients. Common setups
|
412
450
|
are:</p></div>
|
413
|
-
<div class="olist"><ol>
|
451
|
+
<div class="olist arabic"><ol class="arabic">
|
414
452
|
<li>
|
415
453
|
<p>
|
416
454
|
The web application is contained in an application server. This application
|
@@ -422,7 +460,7 @@ understands. Conversely, HTTP responses outputted by the web application are
|
|
422
460
|
sent to the application server, which in turn sends them to the web server,
|
423
461
|
and eventually to the HTTP client.
|
424
462
|
</p>
|
425
|
-
<div class="
|
463
|
+
<div class="paragraph"><p>A typical example of such a setup is a J2EE application, contained in the
|
426
464
|
Tomcat web server, behind the Apache web server.</p></div>
|
427
465
|
</li>
|
428
466
|
<li>
|
@@ -451,86 +489,85 @@ are good examples of this.
|
|
451
489
|
</p>
|
452
490
|
</li>
|
453
491
|
</ol></div>
|
454
|
-
<div class="
|
492
|
+
<div class="paragraph"><p>These descriptions are true for virtually all web applications, whether they’re
|
455
493
|
based on PHP, Django, J2EE, ASP.NET, Ruby on Rails, or whatever. Note that all
|
456
494
|
of these setups provide the same functionality, i.e. no setup can do something
|
457
|
-
that a different setup can
|
495
|
+
that a different setup can’t. The critical reader will notice that all of these
|
458
496
|
setups are identical to the one described in the first diagram, if the
|
459
497
|
combination of web servers, application servers, web applications etc. are
|
460
498
|
considered to be a single entity; a black box if you will.</p></div>
|
461
|
-
<div class="
|
499
|
+
<div class="paragraph"><p>It should also be noted that these setups do not enforce any particular
|
462
500
|
I/O processing implementation. The web servers, application servers, web
|
463
501
|
applications, etc. could process I/O serially (i.e. one request at a time),
|
464
502
|
could multiplex I/O with a single thread (e.g. by using <tt>select(2)</tt> or
|
465
503
|
<tt>poll(2)</tt>) or it could process I/O with multiple threads and/or multiple
|
466
504
|
processes.</p></div>
|
467
|
-
<div class="
|
505
|
+
<div class="paragraph"><p>Of course, there are many variations possible. For example, load balancers
|
468
506
|
could be used. But that is outside the scope of this document.</p></div>
|
469
|
-
<h3 id="_ruby_on_rails">1.2. Ruby on Rails</h3
|
470
|
-
<div class="
|
507
|
+
<h3 id="_ruby_on_rails">1.2. Ruby on Rails</h3>
|
508
|
+
<div class="paragraph"><p>Every Ruby on Rails application has a <em>dispatcher</em>. This dispatcher is
|
471
509
|
responsible for processing HTTP requests. It does not speak HTTP directly.
|
472
510
|
Instead, it accepts data structures that contain the information of an
|
473
511
|
HTTP request. Thus, the dispatcher is particularly interesting to
|
474
512
|
developers who wish to develop software which connects Ruby on Rails to an
|
475
513
|
HTTP processing layer (e.g. a web server).</p></div>
|
476
|
-
<div class="
|
514
|
+
<div class="paragraph"><p>The Ruby on Rails dispatcher can only process requests serially, i.e. one
|
477
515
|
at a time. It is not possible to process two requests at the same time
|
478
516
|
with threads, because parts of Ruby on Rails are not thread-safe. (In
|
479
|
-
practice, this isn
|
517
|
+
practice, this isn’t as big of a problem as some people imagine. This will
|
480
518
|
be elaborated further in <a href="#concurrent_requests">Handling of concurrent requests</a>.)</p></div>
|
481
|
-
<div class="
|
519
|
+
<div class="paragraph"><p>A particularly interesting thing to note, is that a lot of the memory
|
482
520
|
occupied by Ruby on Rails applications is spent on storing the program code
|
483
521
|
(i.e. the <a href="http://en.wikipedia.org/wiki/Abstract_syntax_tree">abstract
|
484
522
|
syntax tree (AST)</a>) in memory. This is observed through the use of the
|
485
523
|
memory statistics function in <a href="http://www.rubyenterpriseedition.com/">Ruby
|
486
524
|
Enterprise Edition</a>. Also, a lot of the startup time of a Ruby on Rails
|
487
525
|
application is spent on bootstrapping the Rails framework.</p></div>
|
488
|
-
<h3 id="_apache">1.3. Apache</h3
|
489
|
-
<div class="
|
526
|
+
<h3 id="_apache">1.3. Apache</h3>
|
527
|
+
<div class="paragraph"><p>The Apache web server has a pluggable I/O multiprocessing (the ability to
|
490
528
|
handle more than 1 concurrent HTTP client at the same time) architecture. An
|
491
529
|
Apache module which implements a particular multiprocessing strategy, is called
|
492
530
|
a Multi-Processing Module (MPM). The
|
493
|
-
<a href="http://httpd.apache.org/docs/2.0/mod/prefork.html">prefork MPM</a
|
494
|
-
also happens to be the default
|
531
|
+
<a href="http://httpd.apache.org/docs/2.0/mod/prefork.html">prefork MPM</a> — which
|
532
|
+
also happens to be the default — appears to be the most popular one. This MPM
|
495
533
|
spawns multiple worker child processes. HTTP requests are first accepted by a
|
496
534
|
so-called control process, and then forwarded to one of the worker processes.
|
497
|
-
The next section contains a diagram which shows the prefork MPM
|
535
|
+
The next section contains a diagram which shows the prefork MPM’s architecture.</p></div>
|
498
536
|
</div>
|
499
537
|
<h2 id="_passenger_architecture">2. Passenger architecture</h2>
|
500
538
|
<div class="sectionbody">
|
501
|
-
<h3 id="_overview">2.1. Overview</h3
|
502
|
-
<div class="
|
539
|
+
<h3 id="_overview">2.1. Overview</h3>
|
540
|
+
<div class="paragraph"><p>Passenger’s architecture is a lot like setup #2 described in
|
503
541
|
<a href="#typical_web_applications">Typical web applications</a>. In other words,
|
504
542
|
Passenger extends Apache and allows it to act like an application server.
|
505
|
-
Passenger
|
506
|
-
|
507
|
-
<
|
508
|
-
<img src="images/passenger_architecture.png" alt="Passenger's architecture" title="Passenger's architecture" />
|
543
|
+
Passenger’s architecture — assuming Apache 2 with the prefork MPM is used — is shown in the following diagram:</p></div>
|
544
|
+
<div class="paragraph"><p><span class="image">
|
545
|
+
<img src="images/passenger_architecture.png" alt="Passenger’s architecture" title="Passenger’s architecture" />
|
509
546
|
</span></p></div>
|
510
|
-
<div class="
|
547
|
+
<div class="paragraph"><p>Passenger consists of an Apache module, <em>mod_passenger</em>. This is written in
|
511
548
|
C++, and can be found in the directory <em>ext/apache2</em>. The module is active in
|
512
549
|
the Apache control process and in all the Apache worker processes. When an
|
513
550
|
HTTP request comes in, <em>mod_passenger</em> will check whether the request should
|
514
551
|
be handled by a Ruby on Rails application. If so, then <em>mod_passenger</em> will
|
515
552
|
spawn the corresponding Rails application (if necessary) and forward the
|
516
553
|
request to that application.</p></div>
|
517
|
-
<div class="
|
554
|
+
<div class="paragraph"><p>It should be noted that the Ruby on Rails application does <strong>not</strong> run in the
|
518
555
|
same address space as Apache. This differentiates Passenger from other
|
519
556
|
application-server-inside-web-server software such as mod_php, mod_perl and
|
520
557
|
mod_ruby. If the Rails application crashes or leak memory, it will have no
|
521
558
|
effect on Apache. In fact, stability is one of our highest goals. Passenger
|
522
|
-
is carefully designed and implemented so that Apache shouldn
|
559
|
+
is carefully designed and implemented so that Apache shouldn’t crash because
|
523
560
|
of Passenger.</p></div>
|
524
|
-
<h3 id="_spawning_and_caching_of_code_and_applications">2.2. Spawning and caching of code and applications</h3
|
525
|
-
<div class="
|
561
|
+
<h3 id="_spawning_and_caching_of_code_and_applications">2.2. Spawning and caching of code and applications</h3>
|
562
|
+
<div class="paragraph"><p>A very naive implementation of Passenger would spawn a Ruby on Rails
|
526
563
|
application every time an HTTP request is received, just like CGI would.
|
527
564
|
However, spawning Ruby on Rails applications is expensive. It can take 1 or 2
|
528
565
|
seconds on a modern PC, and possibly much longer on a heavily loaded server.
|
529
566
|
This overhead is particularily unacceptable on shared hosts. A less naive
|
530
567
|
implementation would keep spawned Ruby on Rails application instances alive,
|
531
|
-
similar to how Lighttpd
|
568
|
+
similar to how Lighttpd’s FastCGI implementation works.
|
532
569
|
However, this still has several problems:</p></div>
|
533
|
-
<div class="olist"><ol>
|
570
|
+
<div class="olist arabic"><ol class="arabic">
|
534
571
|
<li>
|
535
572
|
<p>
|
536
573
|
The first request to a Rails website will be slow, and subsequent requests
|
@@ -540,62 +577,62 @@ The first request to a Rails website will be slow, and subsequent requests
|
|
540
577
|
</li>
|
541
578
|
<li>
|
542
579
|
<p>
|
543
|
-
As we
|
580
|
+
As we’ve explained earlier in this article, a lot of memory in a Rails
|
544
581
|
application is spent on storing the AST of the Ruby on Rails framework and
|
545
582
|
the application. Especially on shared hosts and on memory-constrained
|
546
583
|
Virtual Private Servers (VPS), this can be a problem.
|
547
584
|
</p>
|
548
585
|
</li>
|
549
586
|
</ol></div>
|
550
|
-
<div class="
|
587
|
+
<div class="paragraph"><p>Both of these problems are very much solvable, and we’ve chosen to do just
|
551
588
|
that.</p></div>
|
552
|
-
<div class="
|
589
|
+
<div class="paragraph"><p>The first problem can be solved by preloading Rails applications, i.e. by
|
553
590
|
running the Rails application before a request is ever made to that website.
|
554
591
|
This is the approach taken by most Rails hosts, for example in the form of a
|
555
592
|
Mongrel cluster which is running all the time. However, this is unacceptable
|
556
593
|
for a shared host: such an application would just sit there and waste memory
|
557
|
-
even if it
|
594
|
+
even if it’s not doing anything. Instead, we’ve chosen to take a different
|
558
595
|
approach, which solves both of the aforementioned problems.</p></div>
|
559
|
-
<div class="
|
596
|
+
<div class="paragraph"><p>We spawn Rails applications via a <em>spawn server</em>. The spawn server caches Ruby
|
560
597
|
on Rails framework code and application code in memory. Spawning a Rails
|
561
598
|
application for the first time will still be slow, but subsequent spawn
|
562
599
|
attempts will be very fast. Furthermore, because the framework code is cached
|
563
600
|
independently from the application code, spawning a different Rails application
|
564
601
|
will also be very fast, as long as that application is using a Rails framework
|
565
602
|
version that has already been cached.</p></div>
|
566
|
-
<div class="
|
603
|
+
<div class="paragraph"><p>Another implication of the spawn server is that different Ruby on Rails will
|
567
604
|
share memory with each other, thus solving problem #2. This is described in
|
568
605
|
detail in <a href="#spawn_server">the next section</a>.</p></div>
|
569
|
-
<div class="
|
606
|
+
<div class="paragraph"><p>But despite the caching of framework code and application code, spawning is
|
570
607
|
still expensive compared to an HTTP request. We want to avoid spawning whenever
|
571
|
-
possible. This is why we
|
608
|
+
possible. This is why we’ve introduced the <strong>application pool</strong>. Spawned
|
572
609
|
application instances are kept alive, and their handles are stored into this
|
573
610
|
pool, allowing each application instance to be reused later. Thus, Passenger
|
574
611
|
has very good average case performance.</p></div>
|
575
|
-
<div class="
|
612
|
+
<div class="paragraph"><p>The application pool is shared between different worker processes. Because the
|
576
613
|
worker processes cannot share memory with each other, either shared memory must
|
577
614
|
be used to implement the application pool, or a client/server architecture must
|
578
|
-
be implemented. We
|
615
|
+
be implemented. We’ve chosen the latter because it is easier
|
579
616
|
to implement. The Apache control process acts like a server for the application
|
580
617
|
pool. However, this does not mean that all HTTP request/response data go
|
581
618
|
through the control process. A worker process queries the pool for a connection
|
582
619
|
session with a Rails application. Once this session has been obtained, the
|
583
620
|
worker process will communicate directly with the Rails application.</p></div>
|
584
|
-
<div class="
|
621
|
+
<div class="paragraph"><p>The application pool is implemented inside <em>mod_passenger</em>. One can find
|
585
622
|
detailed documentation about it in
|
586
623
|
<a href="cxxapi/index.html">the C++ API documentation</a>,
|
587
624
|
in particular the documentation about the <tt>ApplicationPool</tt>,
|
588
625
|
<tt>StandardApplicationPool</tt> and <tt>ApplicationPoolServer</tt> classes.</p></div>
|
589
|
-
<div class="
|
626
|
+
<div class="paragraph"><p>The application pool is responsible for spawning applications, caching
|
590
627
|
spawned applications' handles, and cleaning up applications which have been
|
591
628
|
idle for an extended period of time.</p></div>
|
592
|
-
<h3 id="spawn_server">2.3. The spawn server</h3
|
593
|
-
<div class="
|
629
|
+
<h3 id="spawn_server">2.3. The spawn server</h3>
|
630
|
+
<div class="paragraph"><p>The spawn server is written in Ruby, and its code can be found in the directory
|
594
631
|
<em>lib/passenger</em>. Its main executable is <em>bin/passenger-spawn-server</em>.
|
595
|
-
<a href="rdoc/index.html">The spawn server
|
632
|
+
<a href="rdoc/index.html">The spawn server’s RDoc documentation</a> documents the
|
596
633
|
implementation in detail.</p></div>
|
597
|
-
<div class="
|
598
|
-
<div class="olist"><ol>
|
634
|
+
<div class="paragraph"><p>The spawn server consists of 3 logical layers:</p></div>
|
635
|
+
<div class="olist arabic"><ol class="arabic">
|
599
636
|
<li>
|
600
637
|
<p>
|
601
638
|
<strong>The spawn manager.</strong> This is the topmost layer, and acts like a fascade for
|
@@ -624,37 +661,36 @@ implementation in detail.</p></div>
|
|
624
661
|
</p>
|
625
662
|
</li>
|
626
663
|
</ol></div>
|
627
|
-
<div class="
|
628
|
-
<img src="images/spawn_server_architecture.png" alt="The spawn server
|
664
|
+
<div class="paragraph"><p><span class="image">
|
665
|
+
<img src="images/spawn_server_architecture.png" alt="The spawn server’s architecture" title="The spawn server’s architecture" />
|
629
666
|
</span></p></div>
|
630
|
-
<div class="
|
667
|
+
<div class="paragraph"><p>As you can see, we have two layers of code caching: when the spawn server
|
631
668
|
receives a request to spawn a new application instance, it will forward the
|
632
669
|
request to the correct framework spawner server (and will spawn that framework
|
633
|
-
spawner server if it doesn
|
670
|
+
spawner server if it doesn’t already exist), which — in turn — will forward
|
634
671
|
it to the correct application spawner server (which will, again, be created if
|
635
|
-
it doesn
|
636
|
-
<div class="
|
672
|
+
it doesn’t already exist).</p></div>
|
673
|
+
<div class="paragraph"><p>Each layer is only responsible for the layer directly below. The spawn manager
|
637
674
|
only knows about framework spawner servers, and a framework spawner server only
|
638
675
|
knows about its application spawner servers. The application spawner server is,
|
639
676
|
however, not responsible for managing spawned application instances. If an
|
640
677
|
application instance is spawned by mod_passenger, its information will be sent
|
641
678
|
back to mod_passenger, which will be fully responsible for managing the
|
642
|
-
application instance
|
643
|
-
<div class="
|
679
|
+
application instance’s life time (through the application pool).</p></div>
|
680
|
+
<div class="paragraph"><p>Also note that each layer is a seperate process. This is required because a
|
644
681
|
single Ruby process can only load a single Ruby on Rails framework and a
|
645
682
|
single application.</p></div>
|
646
683
|
<h4 id="_memory_sharing">2.3.1. Memory sharing</h4>
|
647
|
-
<div class="
|
684
|
+
<div class="paragraph"><p>On most modern Unix operating systems, when a child process is created, it will
|
648
685
|
share most of its memory with the parent process. Processes are not supposed to
|
649
686
|
be able to access each others' memory, so the operating system makes a copy of
|
650
687
|
a piece of memory when it is written to by the parent process or the child
|
651
688
|
process. This is called copy-on-write (COW). Detailed background information
|
652
689
|
can be found on <a href="http://www.rubyenterpriseedition.com/">Ruby Enterprise
|
653
|
-
Edition
|
654
|
-
<div class="
|
690
|
+
Edition’s website</a>.</p></div>
|
691
|
+
<div class="paragraph"><p>The spawn server makes use of this useful fact. Each layer shares its Ruby AST
|
655
692
|
memory with all of its lower layers, as long as the AST nodes in question
|
656
|
-
haven
|
657
|
-
— if possible — share the Ruby on Rails framework's code, as well as its own
|
693
|
+
haven’t been written to. This means that all spawned Rails applications will — if possible — share the Ruby on Rails framework’s code, as well as its own
|
658
694
|
application code, with each other. This results in a dramatic reduction in
|
659
695
|
memory usage.</p></div>
|
660
696
|
<div class="admonitionblock">
|
@@ -663,28 +699,28 @@ memory usage.</p></div>
|
|
663
699
|
<img src="./images/icons/note.png" alt="Note" />
|
664
700
|
</td>
|
665
701
|
<td class="content">
|
666
|
-
<div class="
|
667
|
-
Enterprise Edition</a> is used. This is because the standard Ruby interpreter
|
668
|
-
garbage collector isn
|
702
|
+
<div class="paragraph"><p>Sharing memory only works if <a href="http://www.rubyenterpriseedition.com/">Ruby
|
703
|
+
Enterprise Edition</a> is used. This is because the standard Ruby interpreter’s
|
704
|
+
garbage collector isn’t copy-on-write friendly. Please visit the Ruby
|
669
705
|
Enterprise Edition website for technical details.</p></div>
|
670
|
-
<div class="
|
671
|
-
startup times. You just won
|
706
|
+
<div class="paragraph"><p>Passenger works fine with standard Ruby. You still get to enjoy reduced Rails
|
707
|
+
startup times. You just won’t be able to benefit from memory sharing.</p></div>
|
672
708
|
</td>
|
673
709
|
</tr></table>
|
674
710
|
</div>
|
675
|
-
<div class="
|
711
|
+
<div class="paragraph"><p>Note that <a href="http://rubini.us/">Rubinius</a>'s garbage collector is already
|
676
712
|
copy-on-write friendly.</p></div>
|
677
|
-
<h3 id="concurrent_requests">2.4. Handling of concurrent requests</h3
|
678
|
-
<div class="
|
713
|
+
<h3 id="concurrent_requests">2.4. Handling of concurrent requests</h3>
|
714
|
+
<div class="paragraph"><p>As explained earlier, a single Rails application instance can only handle a
|
679
715
|
single request at the same time. This is obviously undesirable. But before we
|
680
716
|
dive into the solution, let us take a look how the “competition” solves this
|
681
717
|
problem. PHP has similar problems: a single PHP script can also process only
|
682
718
|
one HTTP request at a time.</p></div>
|
683
|
-
<div class="
|
719
|
+
<div class="ulist"><ul>
|
684
720
|
<li>
|
685
721
|
<p>
|
686
|
-
mod_php “solves” this problem by using Apache
|
687
|
-
mod_php doesn
|
722
|
+
mod_php “solves” this problem by using Apache’s MPM. In other words,
|
723
|
+
mod_php doesn’t do anything by itself at all. A single Apache worker
|
688
724
|
process/thread can only handle 1 PHP request at a time, but Apache spawns
|
689
725
|
multiple worker processes/threads.
|
690
726
|
</p>
|
@@ -698,23 +734,22 @@ PHP-FastCGI solves the problem by spawning multiple persistent PHP servers.
|
|
698
734
|
</p>
|
699
735
|
</li>
|
700
736
|
</ul></div>
|
701
|
-
<div class="
|
702
|
-
Rails application for each request, which is
|
703
|
-
unacceptably slow. Instead, Passenger uses the PHP-FastCGI approach. We
|
737
|
+
<div class="paragraph"><p>Passenger cannot use the mod_php way because it would force us to spawn a new
|
738
|
+
Rails application for each request, which is — as explained earlier — unacceptably slow. Instead, Passenger uses the PHP-FastCGI approach. We
|
704
739
|
maintain a pool of application instances, and whenever a request is received,
|
705
740
|
we forward the request to one of the application instances in the pool. The
|
706
741
|
size of the pool is configurable, which is useful for administrators of servers
|
707
742
|
that are either heavily loaded or have little memory.</p></div>
|
708
|
-
<div class="
|
743
|
+
<div class="paragraph"><p>The reader might also be interested in studying the application pool’s
|
709
744
|
algorithm, which is non-trivial. The algorithm is documented in detail in
|
710
745
|
<a href="ApplicationPool%20algorithm.txt">ApplicationPool algorithm.txt</a>.</p></div>
|
711
746
|
</div>
|
712
747
|
<h2 id="_appendix_a_about_this_document">3. Appendix A: About this document</h2>
|
713
748
|
<div class="sectionbody">
|
714
|
-
<div class="
|
749
|
+
<div class="paragraph"><p>The text of this document is licensed under the
|
715
750
|
<a href="http://creativecommons.org/licenses/by-sa/3.0/">Creative Commons
|
716
751
|
Attribution-Share Alike 3.0 Unported License</a>.</p></div>
|
717
|
-
<div class="
|
752
|
+
<div class="paragraph"><p><span class="image">
|
718
753
|
<a class="image" href="link:http://creativecommons.org/licenses/by-sa/3.0/">
|
719
754
|
<img src="images/by_sa.png" alt="images/by_sa.png" />
|
720
755
|
</a>
|
@@ -722,7 +757,7 @@ Attribution-Share Alike 3.0 Unported License</a>.</p></div>
|
|
722
757
|
</div>
|
723
758
|
<div id="footer">
|
724
759
|
<div id="footer-text">
|
725
|
-
Last updated 2009-
|
760
|
+
Last updated 2009-11-24 04:33:45 PDT
|
726
761
|
</div>
|
727
762
|
</div>
|
728
763
|
</body>
|