passenger 2.1.3 → 2.2.0
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/DEVELOPERS.TXT +2 -0
- data/INSTALL +3 -1
- data/LICENSE +19 -355
- data/NEWS +3 -0
- data/README +11 -4
- data/Rakefile +435 -236
- data/bin/passenger-config +20 -14
- data/bin/passenger-install-apache2-module +67 -201
- data/bin/passenger-install-nginx-module +477 -0
- data/bin/passenger-make-enterprisey +17 -12
- data/bin/passenger-memory-stats +33 -23
- data/bin/passenger-spawn-server +17 -12
- data/bin/passenger-status +18 -13
- data/bin/passenger-stress-test +17 -12
- data/doc/{Users guide.html → Users guide Apache.html } +79 -61
- data/doc/{Users guide.txt → Users guide Apache.txt } +43 -939
- data/doc/Users guide Nginx.html +2276 -0
- data/doc/Users guide Nginx.txt +776 -0
- data/doc/cxxapi/ApplicationPoolServer_8h-source.html +9 -4
- data/doc/cxxapi/ApplicationPool_8h-source.html +9 -4
- data/doc/cxxapi/Application_8h-source.html +26 -21
- data/doc/cxxapi/Bucket_8h-source.html +54 -44
- data/doc/cxxapi/CachedFileStat_8h-source.html +9 -4
- data/doc/cxxapi/Configuration_8h-source.html +357 -339
- data/doc/cxxapi/DirectoryMapper_8h-source.html +294 -280
- data/doc/cxxapi/DummySpawnManager_8h-source.html +9 -4
- data/doc/cxxapi/Exceptions_8h-source.html +9 -4
- data/doc/cxxapi/FileChecker_8h-source.html +9 -4
- data/doc/cxxapi/Hooks_8h-source.html +50 -40
- data/doc/cxxapi/Logging_8h-source.html +9 -4
- data/doc/cxxapi/MessageChannel_8h-source.html +20 -15
- data/doc/cxxapi/PoolOptions_8h-source.html +10 -5
- data/doc/cxxapi/SpawnManager_8h-source.html +9 -4
- data/doc/cxxapi/StandardApplicationPool_8h-source.html +10 -5
- data/doc/cxxapi/SystemTime_8h-source.html +9 -4
- data/doc/cxxapi/Utils_8h-source.html +242 -214
- data/doc/cxxapi/annotated.html +4 -28
- data/doc/cxxapi/classClient-members.html +4 -4
- data/doc/cxxapi/classClient.html +14 -11
- data/doc/cxxapi/classHooks-members.html +4 -5
- data/doc/cxxapi/classHooks.html +26 -24
- data/doc/cxxapi/classPassenger_1_1Application-members.html +4 -4
- data/doc/cxxapi/classPassenger_1_1Application.html +40 -37
- data/doc/cxxapi/classPassenger_1_1ApplicationPool-members.html +4 -4
- data/doc/cxxapi/classPassenger_1_1ApplicationPool.html +95 -92
- data/doc/cxxapi/classPassenger_1_1ApplicationPoolServer-members.html +4 -4
- data/doc/cxxapi/classPassenger_1_1ApplicationPoolServer.html +26 -23
- data/doc/cxxapi/classPassenger_1_1ApplicationPool__inherit__graph.map +1 -1
- data/doc/cxxapi/classPassenger_1_1ApplicationPool__inherit__graph.md5 +1 -1
- data/doc/cxxapi/classPassenger_1_1ApplicationPool__inherit__graph.png +0 -0
- data/doc/cxxapi/classPassenger_1_1Application_1_1Session-members.html +17 -17
- data/doc/cxxapi/classPassenger_1_1Application_1_1Session.html +139 -136
- data/doc/cxxapi/classPassenger_1_1BufferedUpload-members.html +4 -4
- data/doc/cxxapi/classPassenger_1_1BufferedUpload.html +13 -10
- data/doc/cxxapi/classPassenger_1_1BusyException-members.html +4 -4
- data/doc/cxxapi/classPassenger_1_1BusyException.html +11 -8
- data/doc/cxxapi/classPassenger_1_1ConfigurationException-members.html +4 -4
- data/doc/cxxapi/classPassenger_1_1ConfigurationException.html +11 -8
- data/doc/cxxapi/classPassenger_1_1DirectoryMapper-members.html +4 -5
- data/doc/cxxapi/classPassenger_1_1DirectoryMapper.html +45 -43
- data/doc/cxxapi/classPassenger_1_1DummySpawnManager-members.html +4 -4
- data/doc/cxxapi/classPassenger_1_1DummySpawnManager.html +13 -10
- data/doc/cxxapi/classPassenger_1_1FileChecker-members.html +4 -4
- data/doc/cxxapi/classPassenger_1_1FileChecker.html +22 -19
- data/doc/cxxapi/classPassenger_1_1FileNotFoundException-members.html +4 -4
- data/doc/cxxapi/classPassenger_1_1FileNotFoundException.html +12 -9
- data/doc/cxxapi/classPassenger_1_1FileNotFoundException__inherit__graph.map +1 -1
- data/doc/cxxapi/classPassenger_1_1FileNotFoundException__inherit__graph.md5 +1 -1
- data/doc/cxxapi/classPassenger_1_1FileNotFoundException__inherit__graph.png +0 -0
- data/doc/cxxapi/classPassenger_1_1FileSystemException-members.html +4 -4
- data/doc/cxxapi/classPassenger_1_1FileSystemException.html +14 -11
- data/doc/cxxapi/classPassenger_1_1FileSystemException__inherit__graph.map +1 -1
- data/doc/cxxapi/classPassenger_1_1FileSystemException__inherit__graph.md5 +1 -1
- data/doc/cxxapi/classPassenger_1_1FileSystemException__inherit__graph.png +0 -0
- data/doc/cxxapi/classPassenger_1_1IOException-members.html +4 -4
- data/doc/cxxapi/classPassenger_1_1IOException.html +12 -9
- data/doc/cxxapi/classPassenger_1_1IOException__inherit__graph.map +1 -1
- data/doc/cxxapi/classPassenger_1_1IOException__inherit__graph.md5 +1 -1
- data/doc/cxxapi/classPassenger_1_1IOException__inherit__graph.png +0 -0
- data/doc/cxxapi/classPassenger_1_1MessageChannel-members.html +4 -4
- data/doc/cxxapi/classPassenger_1_1MessageChannel.html +228 -225
- data/doc/cxxapi/classPassenger_1_1RuntimeException-members.html +4 -4
- data/doc/cxxapi/classPassenger_1_1RuntimeException.html +11 -8
- data/doc/cxxapi/classPassenger_1_1SpawnException-members.html +4 -4
- data/doc/cxxapi/classPassenger_1_1SpawnException.html +14 -11
- data/doc/cxxapi/classPassenger_1_1SpawnManager-members.html +4 -4
- data/doc/cxxapi/classPassenger_1_1SpawnManager.html +50 -47
- data/doc/cxxapi/classPassenger_1_1StandardApplicationPool-members.html +4 -4
- data/doc/cxxapi/classPassenger_1_1StandardApplicationPool.html +73 -70
- data/doc/cxxapi/classPassenger_1_1StandardApplicationPool__inherit__graph.map +1 -1
- data/doc/cxxapi/classPassenger_1_1StandardApplicationPool__inherit__graph.md5 +1 -1
- data/doc/cxxapi/classPassenger_1_1StandardApplicationPool__inherit__graph.png +0 -0
- data/doc/cxxapi/classPassenger_1_1SystemException-members.html +4 -4
- data/doc/cxxapi/classPassenger_1_1SystemException.html +17 -14
- data/doc/cxxapi/classPassenger_1_1SystemException__inherit__graph.map +1 -1
- data/doc/cxxapi/classPassenger_1_1SystemException__inherit__graph.md5 +1 -1
- data/doc/cxxapi/classPassenger_1_1SystemException__inherit__graph.png +0 -0
- data/doc/cxxapi/classPassenger_1_1SystemTime-members.html +4 -4
- data/doc/cxxapi/classPassenger_1_1SystemTime.html +14 -11
- data/doc/cxxapi/classes.html +35 -0
- data/doc/cxxapi/definitions_8h-source.html +9 -4
- data/doc/cxxapi/doxygen.css +311 -303
- data/doc/cxxapi/files.html +9 -18
- data/doc/cxxapi/functions.html +5 -224
- data/doc/cxxapi/functions_func.html +5 -185
- data/doc/cxxapi/functions_type.html +4 -4
- data/doc/cxxapi/functions_vars.html +4 -4
- data/doc/cxxapi/graph_legend.dot +19 -19
- data/doc/cxxapi/graph_legend.html +5 -5
- data/doc/cxxapi/graph_legend.png +0 -0
- data/doc/cxxapi/group__Configuration.html +11 -13
- data/doc/cxxapi/group__Configuration.png +0 -0
- data/doc/cxxapi/group__Core.html +10 -12
- data/doc/cxxapi/group__Core.png +0 -0
- data/doc/cxxapi/group__Exceptions.html +5 -7
- data/doc/cxxapi/group__Hooks.html +5 -7
- data/doc/cxxapi/group__Hooks.png +0 -0
- data/doc/cxxapi/group__Support.html +5 -624
- data/doc/cxxapi/hierarchy.html +6 -6
- data/doc/cxxapi/inherit__graph__0.map +1 -1
- data/doc/cxxapi/inherit__graph__0.md5 +1 -1
- data/doc/cxxapi/inherit__graph__0.png +0 -0
- data/doc/cxxapi/inherit__graph__1.map +1 -1
- data/doc/cxxapi/inherit__graph__1.md5 +1 -1
- data/doc/cxxapi/inherit__graph__1.png +0 -0
- data/doc/cxxapi/inherit__graph__10.map +1 -1
- data/doc/cxxapi/inherit__graph__10.md5 +1 -1
- data/doc/cxxapi/inherit__graph__10.png +0 -0
- data/doc/cxxapi/inherit__graph__11.map +1 -1
- data/doc/cxxapi/inherit__graph__11.md5 +1 -1
- data/doc/cxxapi/inherit__graph__11.png +0 -0
- data/doc/cxxapi/inherit__graph__12.map +1 -1
- data/doc/cxxapi/inherit__graph__12.md5 +1 -1
- data/doc/cxxapi/inherit__graph__12.png +0 -0
- data/doc/cxxapi/inherit__graph__13.map +1 -2
- data/doc/cxxapi/inherit__graph__13.md5 +1 -1
- data/doc/cxxapi/inherit__graph__13.png +0 -0
- data/doc/cxxapi/inherit__graph__14.map +2 -1
- data/doc/cxxapi/inherit__graph__14.md5 +1 -1
- data/doc/cxxapi/inherit__graph__14.png +0 -0
- data/doc/cxxapi/inherit__graph__15.map +1 -1
- data/doc/cxxapi/inherit__graph__15.md5 +1 -1
- data/doc/cxxapi/inherit__graph__15.png +0 -0
- data/doc/cxxapi/inherit__graph__16.map +1 -1
- data/doc/cxxapi/inherit__graph__16.md5 +1 -1
- data/doc/cxxapi/inherit__graph__16.png +0 -0
- data/doc/cxxapi/inherit__graph__17.map +1 -1
- data/doc/cxxapi/inherit__graph__17.md5 +1 -1
- data/doc/cxxapi/inherit__graph__17.png +0 -0
- data/doc/cxxapi/inherit__graph__18.map +1 -1
- data/doc/cxxapi/inherit__graph__18.md5 +1 -1
- data/doc/cxxapi/inherit__graph__18.png +0 -0
- data/doc/cxxapi/inherit__graph__19.map +1 -1
- data/doc/cxxapi/inherit__graph__19.md5 +1 -1
- data/doc/cxxapi/inherit__graph__19.png +0 -0
- data/doc/cxxapi/inherit__graph__2.map +1 -1
- data/doc/cxxapi/inherit__graph__2.md5 +1 -1
- data/doc/cxxapi/inherit__graph__2.png +0 -0
- data/doc/cxxapi/inherit__graph__20.map +2 -2
- data/doc/cxxapi/inherit__graph__20.md5 +1 -1
- data/doc/cxxapi/inherit__graph__20.png +0 -0
- data/doc/cxxapi/inherit__graph__21.map +1 -1
- data/doc/cxxapi/inherit__graph__21.md5 +1 -1
- data/doc/cxxapi/inherit__graph__21.png +0 -0
- data/doc/cxxapi/inherit__graph__3.map +1 -1
- data/doc/cxxapi/inherit__graph__3.md5 +1 -1
- data/doc/cxxapi/inherit__graph__3.png +0 -0
- data/doc/cxxapi/inherit__graph__4.map +1 -1
- data/doc/cxxapi/inherit__graph__4.md5 +1 -1
- data/doc/cxxapi/inherit__graph__4.png +0 -0
- data/doc/cxxapi/inherit__graph__5.map +1 -2
- data/doc/cxxapi/inherit__graph__5.md5 +1 -1
- data/doc/cxxapi/inherit__graph__5.png +0 -0
- data/doc/cxxapi/inherit__graph__6.map +2 -1
- data/doc/cxxapi/inherit__graph__6.md5 +1 -1
- data/doc/cxxapi/inherit__graph__6.png +0 -0
- data/doc/cxxapi/inherit__graph__7.map +1 -1
- data/doc/cxxapi/inherit__graph__7.md5 +1 -1
- data/doc/cxxapi/inherit__graph__7.png +0 -0
- data/doc/cxxapi/inherit__graph__8.map +1 -1
- data/doc/cxxapi/inherit__graph__8.md5 +1 -1
- data/doc/cxxapi/inherit__graph__8.png +0 -0
- data/doc/cxxapi/inherit__graph__9.map +1 -1
- data/doc/cxxapi/inherit__graph__9.md5 +1 -1
- data/doc/cxxapi/inherit__graph__9.png +0 -0
- data/doc/cxxapi/inherits.html +41 -41
- data/doc/cxxapi/main.html +4 -4
- data/doc/cxxapi/modules.html +4 -5
- data/doc/cxxapi/structPassenger_1_1AnythingToString-members.html +4 -4
- data/doc/cxxapi/structPassenger_1_1AnythingToString.html +13 -10
- data/doc/cxxapi/structPassenger_1_1AnythingToString_3_01vector_3_01string_01_4_01_4-members.html +5 -5
- data/doc/cxxapi/structPassenger_1_1AnythingToString_3_01vector_3_01string_01_4_01_4.html +16 -13
- data/doc/cxxapi/structPassenger_1_1PoolOptions-members.html +4 -4
- data/doc/cxxapi/structPassenger_1_1PoolOptions.html +63 -60
- data/doc/cxxapi/tabs.css +5 -2
- data/doc/cxxapi/tree.html +7 -81
- data/doc/rdoc/classes/ConditionVariable.html +59 -59
- data/doc/rdoc/classes/Exception.html +11 -11
- data/doc/rdoc/classes/GC.html +4 -4
- data/doc/rdoc/classes/IO.html +14 -14
- data/doc/rdoc/classes/PhusionPassenger.html +75 -20
- data/doc/rdoc/classes/PhusionPassenger/AbstractInstaller.html +153 -0
- data/doc/rdoc/classes/PhusionPassenger/AbstractRequestHandler.html +125 -130
- data/doc/rdoc/classes/PhusionPassenger/AbstractServer.html +236 -236
- data/doc/rdoc/classes/PhusionPassenger/AbstractServerCollection.html +213 -213
- data/doc/rdoc/classes/PhusionPassenger/AdminTools.html +28 -28
- data/doc/rdoc/classes/PhusionPassenger/AdminTools/ControlProcess.html +91 -75
- data/doc/rdoc/classes/PhusionPassenger/AppInitError.html +10 -10
- data/doc/rdoc/classes/PhusionPassenger/Application.html +64 -64
- data/doc/rdoc/classes/PhusionPassenger/ConsoleTextTemplate.html +34 -34
- data/doc/rdoc/classes/PhusionPassenger/FrameworkInitError.html +13 -13
- data/doc/rdoc/classes/PhusionPassenger/HTMLTemplate.html +30 -30
- data/doc/rdoc/classes/PhusionPassenger/InitializationError.html +10 -10
- data/doc/rdoc/classes/PhusionPassenger/MessageChannel.html +136 -136
- data/doc/rdoc/classes/PhusionPassenger/NativeSupport.html +24 -24
- data/doc/rdoc/classes/PhusionPassenger/Rack/ApplicationSpawner.html +42 -42
- data/doc/rdoc/classes/PhusionPassenger/Rack/RequestHandler.html +55 -53
- data/doc/rdoc/classes/PhusionPassenger/Railz.html +1 -1
- data/doc/rdoc/classes/PhusionPassenger/Railz/ApplicationSpawner.html +25 -30
- data/doc/rdoc/classes/PhusionPassenger/Railz/CGIFixed.html +23 -23
- data/doc/rdoc/classes/PhusionPassenger/Railz/FrameworkSpawner.html +116 -117
- data/doc/rdoc/classes/PhusionPassenger/Railz/RequestHandler.html +22 -22
- data/doc/rdoc/classes/PhusionPassenger/SpawnManager.html +118 -124
- data/doc/rdoc/classes/PhusionPassenger/UnknownError.html +10 -10
- data/doc/rdoc/classes/PhusionPassenger/Utils.html +354 -354
- data/doc/rdoc/classes/PhusionPassenger/VersionNotFound.html +9 -9
- data/doc/rdoc/classes/PhusionPassenger/WSGI/ApplicationSpawner.html +37 -37
- data/doc/rdoc/classes/PlatformInfo.html +282 -261
- data/doc/rdoc/classes/RakeExtensions.html +7 -7
- data/doc/rdoc/classes/Signal.html +26 -26
- data/doc/rdoc/created.rid +1 -1
- data/doc/rdoc/files/DEVELOPERS_TXT.html +6 -1
- data/doc/rdoc/files/README.html +15 -6
- data/doc/rdoc/files/ext/phusion_passenger/native_support_c.html +1 -1
- data/doc/rdoc/files/lib/phusion_passenger/abstract_installer_rb.html +129 -0
- data/doc/rdoc/files/lib/phusion_passenger/abstract_request_handler_rb.html +20 -13
- data/doc/rdoc/files/lib/phusion_passenger/abstract_server_collection_rb.html +19 -13
- data/doc/rdoc/files/lib/phusion_passenger/abstract_server_rb.html +19 -13
- data/doc/rdoc/files/lib/phusion_passenger/admin_tools/control_process_rb.html +31 -1
- data/doc/rdoc/files/lib/phusion_passenger/admin_tools_rb.html +31 -1
- data/doc/rdoc/files/lib/phusion_passenger/application_rb.html +19 -13
- data/doc/rdoc/files/lib/phusion_passenger/console_text_template_rb.html +19 -13
- data/doc/rdoc/files/lib/phusion_passenger/constants_rb.html +21 -12
- data/doc/rdoc/files/lib/phusion_passenger/dependencies_rb.html +19 -13
- data/doc/rdoc/files/lib/phusion_passenger/events_rb.html +19 -13
- data/doc/rdoc/files/lib/phusion_passenger/exceptions_rb.html +19 -13
- data/doc/rdoc/files/lib/phusion_passenger/html_template_rb.html +19 -13
- data/doc/rdoc/files/lib/phusion_passenger/message_channel_rb.html +19 -13
- data/doc/rdoc/files/lib/phusion_passenger/packaging_rb.html +122 -0
- data/doc/rdoc/files/lib/phusion_passenger/platform_info_rb.html +19 -13
- data/doc/rdoc/files/lib/phusion_passenger/rack/application_spawner_rb.html +22 -12
- data/doc/rdoc/files/lib/phusion_passenger/rack/request_handler_rb.html +21 -12
- data/doc/rdoc/files/lib/phusion_passenger/railz/application_spawner_rb.html +19 -13
- 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 +19 -13
- data/doc/rdoc/files/lib/phusion_passenger/railz/request_handler_rb.html +21 -12
- data/doc/rdoc/files/lib/phusion_passenger/simple_benchmarking_rb.html +19 -13
- data/doc/rdoc/files/lib/phusion_passenger/spawn_manager_rb.html +19 -13
- data/doc/rdoc/files/lib/phusion_passenger/utils_rb.html +27 -21
- data/doc/rdoc/files/lib/phusion_passenger/wsgi/application_spawner_rb.html +21 -12
- data/doc/rdoc/files/misc/rake/extensions_rb.html +21 -12
- data/doc/rdoc/fr_class_index.html +1 -0
- data/doc/rdoc/fr_file_index.html +2 -0
- data/doc/rdoc/fr_method_index.html +116 -112
- data/doc/users_guide_snippets/analysis_and_system_maintenance_tools.txt +144 -0
- data/doc/users_guide_snippets/appendix_a_about.txt +13 -0
- data/doc/users_guide_snippets/appendix_b_terminology.txt +63 -0
- data/doc/users_guide_snippets/appendix_c_spawning_methods.txt +304 -0
- data/doc/users_guide_snippets/global_queueing_explained.txt +78 -0
- data/doc/users_guide_snippets/rackup_specifications.txt +75 -0
- data/doc/users_guide_snippets/rails_spawn_method.txt +48 -0
- data/doc/users_guide_snippets/tips.txt +173 -0
- data/ext/apache2/Bucket.cpp +17 -12
- data/ext/apache2/Bucket.h +17 -12
- data/ext/apache2/Configuration.cpp +17 -12
- data/ext/apache2/Configuration.h +27 -14
- data/ext/apache2/DirectoryMapper.h +21 -12
- data/ext/apache2/Hooks.cpp +67 -21
- data/ext/apache2/Hooks.h +17 -12
- data/ext/apache2/mod_passenger.c +17 -12
- data/ext/{apache2 → common}/Application.h +19 -14
- data/ext/{apache2 → common}/ApplicationPool.h +17 -12
- data/ext/{apache2 → common}/ApplicationPoolServer.h +18 -72
- data/ext/{apache2 → common}/ApplicationPoolServerExecutable.cpp +45 -104
- data/ext/common/ApplicationPoolStatusReporter.h +212 -0
- data/ext/{apache2 → common}/CachedFileStat.cpp +17 -12
- data/ext/{apache2 → common}/CachedFileStat.h +17 -12
- data/ext/{apache2 → common}/DummySpawnManager.h +17 -12
- data/ext/{apache2 → common}/Exceptions.h +17 -12
- data/ext/{apache2 → common}/FileChecker.h +17 -12
- data/ext/common/Logging.cpp +65 -0
- data/ext/{apache2 → common}/Logging.h +17 -12
- data/ext/{apache2 → common}/MessageChannel.h +17 -12
- data/ext/{apache2 → common}/PoolOptions.h +17 -12
- data/ext/{apache2 → common}/SpawnManager.h +17 -12
- data/ext/{apache2 → common}/StandardApplicationPool.h +17 -12
- data/ext/common/StaticString.h +147 -0
- data/ext/common/SystemTime.cpp +33 -0
- data/ext/{apache2 → common}/SystemTime.h +17 -12
- data/ext/{apache2 → common}/Utils.cpp +69 -12
- data/ext/{apache2 → common}/Utils.h +41 -12
- data/ext/nginx/Configuration.c +1091 -0
- data/ext/nginx/Configuration.h +71 -0
- data/ext/nginx/ContentHandler.c +1154 -0
- data/ext/nginx/ContentHandler.h +64 -0
- data/ext/nginx/HelperServer.cpp +857 -0
- data/ext/nginx/HttpStatusExtractor.h +161 -0
- data/ext/nginx/ScgiRequestParser.h +317 -0
- data/ext/nginx/StaticContentHandler.c +222 -0
- data/ext/nginx/StaticContentHandler.h +37 -0
- data/ext/nginx/config +41 -0
- data/ext/nginx/ngx_http_passenger_module.c +572 -0
- data/ext/nginx/ngx_http_passenger_module.h +72 -0
- data/ext/oxt/backtrace.cpp +8 -1
- data/ext/oxt/system_calls.cpp +40 -0
- data/ext/oxt/system_calls.hpp +14 -7
- data/ext/phusion_passenger/extconf.rb +17 -12
- data/ext/phusion_passenger/native_support.c +19 -12
- data/lib/phusion_passenger/abstract_installer.rb +196 -0
- data/lib/phusion_passenger/abstract_request_handler.rb +19 -24
- data/lib/phusion_passenger/abstract_server.rb +17 -12
- data/lib/phusion_passenger/abstract_server_collection.rb +17 -12
- data/lib/phusion_passenger/admin_tools.rb +23 -0
- data/lib/phusion_passenger/admin_tools/control_process.rb +39 -13
- data/lib/phusion_passenger/application.rb +17 -12
- data/lib/phusion_passenger/console_text_template.rb +17 -12
- data/lib/phusion_passenger/constants.rb +22 -11
- data/lib/phusion_passenger/dependencies.rb +47 -12
- data/lib/phusion_passenger/events.rb +17 -12
- data/lib/phusion_passenger/exceptions.rb +17 -12
- data/lib/phusion_passenger/html_template.rb +17 -12
- data/lib/phusion_passenger/message_channel.rb +17 -12
- data/lib/phusion_passenger/packaging.rb +39 -0
- data/lib/phusion_passenger/platform_info.rb +48 -22
- data/lib/phusion_passenger/rack/application_spawner.rb +22 -11
- data/lib/phusion_passenger/rack/request_handler.rb +21 -12
- data/lib/phusion_passenger/railz/application_spawner.rb +23 -23
- data/lib/phusion_passenger/railz/framework_spawner.rb +18 -14
- data/lib/phusion_passenger/railz/request_handler.rb +18 -11
- data/lib/phusion_passenger/simple_benchmarking.rb +17 -12
- data/lib/phusion_passenger/spawn_manager.rb +17 -20
- data/lib/phusion_passenger/templates/{apache_must_be_compiled_with_compatible_mpm.txt.erb → apache2/apache_must_be_compiled_with_compatible_mpm.txt.erb} +0 -0
- data/lib/phusion_passenger/templates/{apache2_config_snippets.txt.erb → apache2/config_snippets.txt.erb} +0 -0
- data/lib/phusion_passenger/templates/{deployment_example.txt.erb → apache2/deployment_example.txt.erb} +0 -0
- data/lib/phusion_passenger/templates/{no_write_permission_to_passenger_root.txt.erb → apache2/no_write_permission_to_passenger_root.txt.erb} +0 -0
- data/lib/phusion_passenger/templates/{possible_solutions_for_compilation_and_installation_problems.txt.erb → apache2/possible_solutions_for_compilation_and_installation_problems.txt.erb} +0 -0
- data/lib/phusion_passenger/templates/{run_installer_as_root.txt.erb → apache2/run_installer_as_root.txt.erb} +0 -0
- data/lib/phusion_passenger/templates/{welcome.txt.erb → apache2/welcome.txt.erb} +0 -0
- data/lib/phusion_passenger/templates/nginx/ask_for_extra_configure_flags.txt.erb +8 -0
- data/lib/phusion_passenger/templates/nginx/cannot_write_to_dir.txt.erb +11 -0
- data/lib/phusion_passenger/templates/nginx/config_snippets.txt.erb +17 -0
- data/lib/phusion_passenger/templates/nginx/config_snippets_inserted.txt.erb +20 -0
- data/lib/phusion_passenger/templates/nginx/confirm_extra_configure_flags.txt.erb +5 -0
- data/lib/phusion_passenger/templates/nginx/deployment_example.txt.erb +22 -0
- data/lib/phusion_passenger/templates/nginx/pcre_could_not_be_downloaded.txt.erb +11 -0
- data/lib/phusion_passenger/templates/nginx/pcre_could_not_be_extracted.txt.erb +11 -0
- data/lib/phusion_passenger/templates/nginx/possible_solutions_for_compilation_and_installation_problems.txt.erb +11 -0
- data/lib/phusion_passenger/templates/nginx/possible_solutions_for_download_and_extraction_problems.txt.erb +20 -0
- data/lib/phusion_passenger/templates/nginx/query_download_and_install.txt.erb +21 -0
- data/lib/phusion_passenger/templates/nginx/run_installer_as_root.txt.erb +8 -0
- data/lib/phusion_passenger/templates/nginx/welcome.txt.erb +15 -0
- data/lib/phusion_passenger/utils.rb +20 -15
- data/lib/phusion_passenger/wsgi/application_spawner.rb +18 -11
- data/lib/phusion_passenger/wsgi/request_handler.py +23 -0
- data/misc/copy_boost_headers.rb +23 -0
- data/misc/find_owner_pipe_leaks.rb +18 -11
- data/misc/rake/cplusplus.rb +18 -11
- data/misc/rake/extensions.rb +21 -14
- data/misc/render_error_pages.rb +18 -11
- data/test/ApplicationPoolServerTest.cpp +1 -3
- data/test/ApplicationPoolServer_ApplicationPoolTest.cpp +1 -1
- data/test/CxxTestMain.cpp +19 -3
- data/test/HttpStatusExtractorTest.cpp +181 -0
- data/test/ScgiRequestParserTest.cpp +337 -0
- data/test/StaticStringTest.cpp +51 -0
- data/test/UtilsTest.cpp +32 -0
- data/test/config.yml.example +5 -0
- data/test/{integration_tests.rb → integration_tests/apache2_tests.rb} +7 -299
- data/test/integration_tests/hello_world_rack_spec.rb +36 -0
- data/test/integration_tests/hello_world_wsgi_spec.rb +41 -0
- data/test/integration_tests/mycook_spec.rb +192 -0
- data/test/integration_tests/nginx_tests.rb +98 -0
- data/test/ruby/rack/application_spawner_spec.rb +40 -0
- data/test/stub/nginx/koi-utf +109 -0
- data/test/stub/nginx/koi-win +103 -0
- data/test/stub/nginx/mime.types +70 -0
- data/test/stub/nginx/nginx.conf.erb +57 -0
- data/test/stub/nginx/win-utf +126 -0
- data/test/stub/rails_apps/mycook/app/controllers/uploads_controller.rb +4 -0
- data/test/stub/rails_apps/mycook/config/routes.rb +1 -1
- data/test/stub/wsgi/passenger_wsgi.pyc +0 -0
- data/test/support/Support.h +40 -0
- data/test/support/nginx_controller.rb +98 -0
- data/test/support/test_helper.rb +79 -0
- metadata +1091 -1028
- data/benchmark/DummyRequestHandler.cpp +0 -101
- data/ext/apache2/Logging.cpp +0 -60
- data/ext/apache2/SystemTime.cpp +0 -28
@@ -103,12 +103,15 @@ be located in the `sbin` folder instead of the `bin` folder.
|
|
103
103
|
NOTE: You can skip this section if you've installed Phusion Passenger via a
|
104
104
|
native Linux package, because no compilation is necessary.
|
105
105
|
|
106
|
-
If your system has multiple Ruby installations
|
107
|
-
MacOS X
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
106
|
+
If your system has multiple Ruby installations -- which is likely the case on
|
107
|
+
MacOS X, or if you've also installed
|
108
|
+
link:http://www.rubyenterpriseedition.com[Ruby Enterprise Edition] -- then you
|
109
|
+
will need to tell the operating system which Ruby installation to use, prior to
|
110
|
+
running the Phusion Passenger installer. If you only have one Ruby installation
|
111
|
+
(the case on most Linux systems), then you can skip this section because Phusion
|
112
|
+
Passenger will automatically detect it.
|
113
|
+
|
114
|
+
To specify a Ruby installation, prepend your Ruby installation's `bin`
|
112
115
|
directory to the `PATH` environment variable. For example, if you have the
|
113
116
|
following Ruby installations:
|
114
117
|
|
@@ -148,8 +151,8 @@ sudo apt-get install libapache2-mod-passenger
|
|
148
151
|
|
149
152
|
==== Installing via the source tarball ====
|
150
153
|
|
151
|
-
Extract the tarball to whatever location you prefer. The Phusion Passenger files
|
152
|
-
are to reside in that location permanently
|
154
|
+
Extract the tarball to whatever location you prefer. *The Phusion Passenger files
|
155
|
+
are to reside in that location permanently.* For example, if you would like
|
153
156
|
Phusion Passenger to reside in `/opt/passenger-x.x.x`:
|
154
157
|
------------------------------------------------------
|
155
158
|
cd /opt
|
@@ -178,6 +181,11 @@ on installing Phusion Passenger on OS X].
|
|
178
181
|
|
179
182
|
Ben Hughes has written an link:http://www.railsgarden.com/2008/04/12/configurating-passenger-mod_rails-on-slicehost-with-ubuntu-710/[article on installing Phusion Passenger on Ubuntu].
|
180
183
|
|
184
|
+
==== OpenSolaris ====
|
185
|
+
|
186
|
+
J. Aaron Farr has written a link:http://cubiclemuses.com/cm/articles/2009/04/09/rails-passenger-open-solaris-ec2/[guide]
|
187
|
+
about setting up Ruby on Rails and Phusion Passenger on OpenSolaris and EC2.
|
188
|
+
|
181
189
|
|
182
190
|
== Deploying a Ruby on Rails application ==
|
183
191
|
|
@@ -433,82 +441,7 @@ touch /webapps/rackapp/tmp/restart.txt
|
|
433
441
|
-------------------------------------------
|
434
442
|
|
435
443
|
=== Rackup specifications for various web frameworks ===
|
436
|
-
|
437
|
-
This subsection shows example 'config.ru' files for various web frameworks.
|
438
|
-
|
439
|
-
==== Camping ====
|
440
|
-
------------------------------------------------------
|
441
|
-
require 'rubygems'
|
442
|
-
require 'rack'
|
443
|
-
require 'camping'
|
444
|
-
|
445
|
-
##### Begin Camping application
|
446
|
-
Camping.goes :Blog
|
447
|
-
|
448
|
-
...your application code here...
|
449
|
-
##### End Camping application
|
450
|
-
|
451
|
-
run Rack::Adapter::Camping.new(Blog)
|
452
|
-
------------------------------------------------------
|
453
|
-
|
454
|
-
For Camping versions 2.0 and up, using `run Blog` as the final line will do.
|
455
|
-
|
456
|
-
==== Halcyon ====
|
457
|
-
------------------------------------------------------
|
458
|
-
require 'rubygems'
|
459
|
-
require 'halcyon'
|
460
|
-
$LOAD_PATH.unshift(Halcyon.root / 'lib')
|
461
|
-
Halcyon::Runner.load_config Halcyon.root/'config'/'config.yml'
|
462
|
-
run Halcyon::Runner.new
|
463
|
-
------------------------------------------------------
|
464
|
-
|
465
|
-
==== Mack ====
|
466
|
-
------------------------------------------------------
|
467
|
-
ENV["MACK_ENV"] = ENV["RACK_ENV"]
|
468
|
-
load("Rakefile")
|
469
|
-
require 'rubygems'
|
470
|
-
require 'mack'
|
471
|
-
run Mack::Utils::Server.build_app
|
472
|
-
------------------------------------------------------
|
473
|
-
|
474
|
-
==== Merb ====
|
475
|
-
------------------------------------------------------
|
476
|
-
require 'rubygems'
|
477
|
-
require 'merb-core'
|
478
|
-
|
479
|
-
Merb::Config.setup(
|
480
|
-
:merb_root => File.expand_path(File.dirname(__FILE__)),
|
481
|
-
:environment => ENV['RACK_ENV']
|
482
|
-
)
|
483
|
-
Merb.environment = Merb::Config[:environment]
|
484
|
-
Merb.root = Merb::Config[:merb_root]
|
485
|
-
Merb::BootLoader.run
|
486
|
-
|
487
|
-
run Merb::Rack::Application.new
|
488
|
-
------------------------------------------------------
|
489
|
-
|
490
|
-
==== Ramaze ====
|
491
|
-
------------------------------------------------------
|
492
|
-
require "start"
|
493
|
-
Ramaze.trait[:essentials].delete Ramaze::Adapter
|
494
|
-
Ramaze.start :force => true
|
495
|
-
run Ramaze::Adapter::Base
|
496
|
-
------------------------------------------------------
|
497
|
-
|
498
|
-
==== Sinatra ====
|
499
|
-
------------------------------------------------------
|
500
|
-
require 'rubygems'
|
501
|
-
require 'sinatra'
|
502
|
-
|
503
|
-
root_dir = File.dirname(__FILE__)
|
504
|
-
|
505
|
-
set :environment, ENV['RACK_ENV'].to_sym
|
506
|
-
set :root, root_dir
|
507
|
-
set :app_file, File.join(root_dir, 'app.rb')
|
508
|
-
disable :run
|
509
|
-
|
510
|
-
run Sinatra::Application
|
511
|
-
------------------------------------------------------
|
444
|
+
include::users_guide_snippets/rackup_specifications.txt[]
|
512
445
|
|
513
446
|
|
514
447
|
== Configuring Phusion Passenger ==
|
@@ -520,8 +453,12 @@ following configuration options:
|
|
520
453
|
|
521
454
|
=== PassengerRoot <directory> ===
|
522
455
|
The location to the Phusion Passenger root directory. This configuration option
|
523
|
-
is essential to Phusion Passenger
|
524
|
-
|
456
|
+
is essential to Phusion Passenger, and allows Phusion Passenger to locate its own
|
457
|
+
data files. The correct value is given by the installer.
|
458
|
+
|
459
|
+
If you've moved Phusion Passenger to a different directory then you need to update
|
460
|
+
this option as well. Please read
|
461
|
+
<<moving_phusion_passenger,Moving Phusion Passenger to a different directory>> for more information.
|
525
462
|
|
526
463
|
This required option may only occur once, in the global server configuration.
|
527
464
|
|
@@ -589,84 +526,7 @@ In each place, it may be specified at most once. The default value is 'off'.
|
|
589
526
|
|
590
527
|
'This feature is sponsored by http://www.37signals.com/[37signals].'
|
591
528
|
|
592
|
-
.
|
593
|
-
|
594
|
-
Recall that Phusion Passenger spawns multiple backend processes (e.g. multiple
|
595
|
-
Ruby on Rails processes), each which processes HTTP requests serially. One of
|
596
|
-
Phusion Passenger's jobs is to forward HTTP requests to a suitable backend
|
597
|
-
process. A backend process may take an arbitrary amount of time to process a
|
598
|
-
specific HTTP request. If the websites are (temporarily) under high load, and
|
599
|
-
the backend processes cannot process the requests fast enough, then some
|
600
|
-
requests may have to be queued.
|
601
|
-
|
602
|
-
If global queuing is turned off, then Phusion Passenger will use 'fair load
|
603
|
-
balancing'. This means that each backend process will have its own private
|
604
|
-
queue. Phusion Passenger will forward an HTTP request to the backend process
|
605
|
-
that has the least amount of requests in its queue.
|
606
|
-
|
607
|
-
If global queuing is turned on, then Phusion Passenger will use a global queue
|
608
|
-
that's shared between all backend processes. If an HTTP request comes in, and
|
609
|
-
all the backend processes are still busy, then Phusion Passenger will wait until
|
610
|
-
at least one backend process is done, and will then forward the request to that
|
611
|
-
process.
|
612
|
-
|
613
|
-
.When to turn on global queuing?
|
614
|
-
|
615
|
-
You should turn on global queuing if one of your web applications may have
|
616
|
-
long-running requests.
|
617
|
-
|
618
|
-
For example suppose that:
|
619
|
-
|
620
|
-
- global queuing is turned off.
|
621
|
-
- we're currently in a state where all backend processes have 3 requests in
|
622
|
-
their queue, except for a single backend process, which has 1 request in its
|
623
|
-
queue.
|
624
|
-
|
625
|
-
The situation looks like this:
|
626
|
-
|
627
|
-
--------------------------------------------------
|
628
|
-
Backend process A: [* ] (1 request in queue)
|
629
|
-
Backend process B: [*** ] (3 requests in queue)
|
630
|
-
Backend process C: [*** ] (3 requests in queue)
|
631
|
-
Backend process D: [*** ] (3 requests in queue)
|
632
|
-
--------------------------------------------------
|
633
|
-
|
634
|
-
Each process is currently serving short-running requests.
|
635
|
-
|
636
|
-
Phusion Passenger will forward the next request to backend process A. A will
|
637
|
-
now have 2 items in its queue. We'll mark this new request with an X:
|
638
|
-
|
639
|
-
--------------------------------------------------
|
640
|
-
Backend process A: [*X ] (2 request in queue)
|
641
|
-
Backend process B: [*** ] (3 requests in queue)
|
642
|
-
Backend process C: [*** ] (3 requests in queue)
|
643
|
-
Backend process D: [*** ] (3 requests in queue)
|
644
|
-
--------------------------------------------------
|
645
|
-
|
646
|
-
Assuming that B, C and D still aren't done with their current request, the next
|
647
|
-
HTTP request - let's call this Y - will be forwarded to backend process A as
|
648
|
-
well, because it has the least number of items in its queue:
|
649
|
-
|
650
|
-
--------------------------------------------------
|
651
|
-
Backend process A: [*XY ] (3 requests in queue)
|
652
|
-
Backend process B: [*** ] (3 requests in queue)
|
653
|
-
Backend process C: [*** ] (3 requests in queue)
|
654
|
-
Backend process D: [*** ] (3 requests in queue)
|
655
|
-
--------------------------------------------------
|
656
|
-
|
657
|
-
But if request X happens to be a long-running request that needs 60 seconds to
|
658
|
-
complete, then we'll have a problem. Y won't be processed for at least 60
|
659
|
-
seconds. It would have been a better idea if Y was forward to processes B, C or
|
660
|
-
D instead, because they only have short-living requests in their queues.
|
661
|
-
|
662
|
-
This problem will be avoided entirely if you turn global queuing on. With global
|
663
|
-
queuing, all backend processes will share the same queue. The first backend
|
664
|
-
process that becomes available will take from the queue, and so this
|
665
|
-
``queuing-behind-long-running-request'' problem will never occur.
|
666
|
-
|
667
|
-
Turning global queuing off will yield a minor performance improvement (about 5%,
|
668
|
-
depending on how fast/slow your web application is), which is why it's off by
|
669
|
-
default.
|
529
|
+
include::users_guide_snippets/global_queueing_explained.txt[]
|
670
530
|
|
671
531
|
|
672
532
|
[[PassengerUserSwitching]]
|
@@ -678,7 +538,7 @@ The default value is 'on'.
|
|
678
538
|
|
679
539
|
[[PassengerDefaultUser]]
|
680
540
|
=== PassengerDefaultUser <username> ===
|
681
|
-
Passenger enables <<user_switching,user switching support>> by default.
|
541
|
+
Phusion Passenger enables <<user_switching,user switching support>> by default.
|
682
542
|
This configuration option allows one to specify which user Rails/Rack
|
683
543
|
applications must run as, if user switching fails or is disabled.
|
684
544
|
|
@@ -1080,54 +940,7 @@ However, we do recommend you to try to understand it. The 'smart' and 'smart-lv2
|
|
1080
940
|
methods bring many benefits.
|
1081
941
|
=========================================================
|
1082
942
|
|
1083
|
-
|
1084
|
-
requests. But there are multiple ways with which processes can be spawned, each having
|
1085
|
-
its own set of pros and cons. Supported spawn methods are:
|
1086
|
-
|
1087
|
-
'smart'::
|
1088
|
-
When this spawn method is used, Phusion Passenger will attempt to cache Ruby on Rails
|
1089
|
-
framework code and application code for a limited period of time. Please read
|
1090
|
-
<<spawning_methods_explained,Spawning methods explained>> for a more detailed
|
1091
|
-
explanation of what smart spawning exactly does.
|
1092
|
-
+
|
1093
|
-
*Pros:*
|
1094
|
-
This can significantly decrease spawn time (by as much as 90%). And, when Ruby Enterprise
|
1095
|
-
Edition is used, <<reducing_memory_usage,memory usage can be reduced by 33% on average>>.
|
1096
|
-
+
|
1097
|
-
*Cons:*
|
1098
|
-
Some Ruby on Rails applications and libraries are not compatible with smart spawning.
|
1099
|
-
If that's the case for your application, then you should use 'conservative' as
|
1100
|
-
spawning method.
|
1101
|
-
|
1102
|
-
'smart-lv2'::
|
1103
|
-
This spawning method is similar to 'smart' but it skips the framework spawner
|
1104
|
-
and uses the application spawner directly. This means the framework code is not
|
1105
|
-
cached between multiple applications, although it is still cached within
|
1106
|
-
instances of the same application. Please read
|
1107
|
-
<<spawning_methods_explained,Spawning methods explained>> for a more detailed
|
1108
|
-
explanation of what smart-lv2 spawning exactly does.
|
1109
|
-
+
|
1110
|
-
*Pros:* It is compatible with a larger number of applications when compared to
|
1111
|
-
the 'smart' method, and still performs some caching.
|
1112
|
-
+
|
1113
|
-
*Cons:* It is slower than smart spawning if you have many applications which
|
1114
|
-
use the same framework version. It is therefore advised that shared hosts use the
|
1115
|
-
'smart' method instead.
|
1116
|
-
|
1117
|
-
'conservative'::
|
1118
|
-
This spawning method is similar to the one used in Mongrel Cluster. It does not
|
1119
|
-
perform any code caching at all. Please read
|
1120
|
-
<<spawning_methods_explained,Spawning methods explained>> for a more detailed
|
1121
|
-
explanation of what conservative spawning exactly does.
|
1122
|
-
+
|
1123
|
-
*Pros:*
|
1124
|
-
Conservative spawning is guaranteed to be compatible with all Rails applications
|
1125
|
-
and libraries.
|
1126
|
-
+
|
1127
|
-
*Cons:*
|
1128
|
-
Much slower than smart spawning. Every spawn action will be equally slow, though no slower than
|
1129
|
-
the startup time of a single server in Mongrel Cluster. Conservative spawning will also
|
1130
|
-
render <<reducing_memory_usage,Ruby Enterprise Edition's memory reduction technology>> useless.
|
943
|
+
include::users_guide_snippets/rails_spawn_method.txt[]
|
1131
944
|
|
1132
945
|
This option may occur in the following places:
|
1133
946
|
|
@@ -1153,8 +966,12 @@ you're using the 'smart' <<RailsSpawnMethod,spawning method>>. So if your
|
|
1153
966
|
system has enough memory, is it recommended that you set this option to a high
|
1154
967
|
value or to '0'.
|
1155
968
|
|
1156
|
-
This option may
|
1157
|
-
|
969
|
+
This option may occur in the following places:
|
970
|
+
|
971
|
+
* In the global server configuration.
|
972
|
+
* In a virtual host configuration block.
|
973
|
+
|
974
|
+
In each place, it may be specified at most once. The default value is '1800' (30 minutes).
|
1158
975
|
|
1159
976
|
==== RailsAppSpawnerIdleTime <integer> ====
|
1160
977
|
The ApplicationSpawner server (explained in <<spawning_methods_explained,Spawning
|
@@ -1173,8 +990,12 @@ you're using the 'smart' or 'smart-lv2' <<RailsSpawnMethod,spawning method>>. So
|
|
1173
990
|
system has enough memory, is it recommended that you set this option to a high
|
1174
991
|
value or to '0'.
|
1175
992
|
|
1176
|
-
This option may
|
1177
|
-
|
993
|
+
This option may occur in the following places:
|
994
|
+
|
995
|
+
* In the global server configuration.
|
996
|
+
* In a virtual host configuration block.
|
997
|
+
|
998
|
+
In each place, it may be specified at most once. The default value is '600' (10 minutes).
|
1178
999
|
|
1179
1000
|
=== Rack-specific options ===
|
1180
1001
|
|
@@ -1578,291 +1399,12 @@ VirtualDocumentRoot is not compatible with Phusion Passenger at the moment.
|
|
1578
1399
|
|
1579
1400
|
== Analysis and system maintenance tools ==
|
1580
1401
|
|
1581
|
-
|
1582
|
-
maintenance and troubleshooting.
|
1583
|
-
|
1584
|
-
|
1585
|
-
=== Inspecting memory usage ===
|
1586
|
-
|
1587
|
-
Process inspection tools such as `ps` and `top` are useful, but they
|
1588
|
-
link:http://groups.google.com/group/phusion-passenger/msg/1fd1c233456d3180[rarely show the correct memory usage].
|
1589
|
-
The real memory usage is usually lower than what `ps` and `top` report.
|
1590
|
-
|
1591
|
-
There are many technical reasons why this is so, but an explanation is beyond
|
1592
|
-
the scope of this Users Guide. We kindly refer the interested reader to
|
1593
|
-
operating systems literature about 'virtual memory' and 'copy-on-write'.
|
1594
|
-
|
1595
|
-
The tool `passenger-memory-stats` allows one to easily analyze Phusion Passenger's
|
1596
|
-
and Apache's real memory usage. For example:
|
1597
|
-
|
1598
|
-
-------------------------------------------------------
|
1599
|
-
[bash@localhost root]# passenger-memory-stats
|
1600
|
-
------------- Apache processes --------------.
|
1601
|
-
PID PPID Threads VMSize Private Name
|
1602
|
-
---------------------------------------------.
|
1603
|
-
5947 1 9 90.6 MB 0.5 MB /usr/sbin/apache2 -k start
|
1604
|
-
5948 5947 1 18.9 MB 0.7 MB /usr/sbin/fcgi-pm -k start
|
1605
|
-
6029 5947 1 42.7 MB 0.5 MB /usr/sbin/apache2 -k start
|
1606
|
-
6030 5947 1 42.7 MB 0.5 MB /usr/sbin/apache2 -k start
|
1607
|
-
6031 5947 1 42.5 MB 0.3 MB /usr/sbin/apache2 -k start
|
1608
|
-
6033 5947 1 42.5 MB 0.4 MB /usr/sbin/apache2 -k start
|
1609
|
-
6034 5947 1 50.5 MB 0.4 MB /usr/sbin/apache2 -k start
|
1610
|
-
23482 5947 1 82.6 MB 0.4 MB /usr/sbin/apache2 -k start
|
1611
|
-
### Processes: 8
|
1612
|
-
### Total private dirty RSS: 3.50 MB
|
1613
|
-
|
1614
|
-
--------- Passenger processes ---------.
|
1615
|
-
PID Threads VMSize Private Name
|
1616
|
-
---------------------------------------.
|
1617
|
-
6026 1 10.9 MB 4.7 MB Passenger spawn server
|
1618
|
-
23481 1 26.7 MB 3.0 MB Passenger FrameworkSpawner: 2.0.2
|
1619
|
-
23791 1 26.8 MB 2.9 MB Passenger ApplicationSpawner: /var/www/projects/app1-foobar
|
1620
|
-
23793 1 26.9 MB 17.1 MB Rails: /var/www/projects/app1-foobar
|
1621
|
-
### Processes: 4
|
1622
|
-
### Total private dirty RSS: 27.76 M
|
1623
|
-
-------------------------------------------------------
|
1624
|
-
|
1625
|
-
The 'Private' or 'private dirty RSS' field shows the *real* memory usage of processes. Here,
|
1626
|
-
we see that all the Apache worker processes only take less than 1 MB memory each.
|
1627
|
-
This is a lot less than the 50 MB-ish memory usage as shown in the 'VMSize' column
|
1628
|
-
(which is what a lot of people think is the real memory usage, but is actually not).
|
1629
|
-
|
1630
|
-
NOTE: This tool only works on Linux. Unfortunately other operating systems don't
|
1631
|
-
provide facilities for determining processes' private dirty RSS.
|
1632
|
-
|
1633
|
-
|
1634
|
-
=== Inspecting Phusion Passenger's internal status ===
|
1635
|
-
|
1636
|
-
One can inspect Phusion Passenger's internal status with the tool `passenger-status`.
|
1637
|
-
This tool must typically be run as root. For example:
|
1638
|
-
|
1639
|
-
--------------------------------------------------
|
1640
|
-
[bash@localhost root]# passenger-status
|
1641
|
-
----------- General information -----------
|
1642
|
-
max = 6
|
1643
|
-
count = 1
|
1644
|
-
active = 0
|
1645
|
-
inactive = 1
|
1646
|
-
|
1647
|
-
----------- Domains -----------
|
1648
|
-
/var/www/projects/app1-foobar:
|
1649
|
-
PID: 9617 Sessions: 0 Processed: 7 Uptime: 2m 23s
|
1650
|
-
--------------------------------------------------
|
1651
|
-
|
1652
|
-
The 'general information' section shows the following information:
|
1653
|
-
|
1654
|
-
max:: The maximum number of application instances that Phusion Passenger will
|
1655
|
-
spawn. This equals the value given for <<PassengerMaxPoolSize,PassengerMaxPoolSize>>.
|
1656
|
-
count:: The number of application instances that are currently alive. This value
|
1657
|
-
is always less than or equal to 'max'.
|
1658
|
-
active:: The number of application instances that are currently processing
|
1659
|
-
requests. This value is always less than or equal to 'count'.
|
1660
|
-
inactive:: The number of application instances that are currently *not* processing
|
1661
|
-
requests, i.e. are idle. Idle application instances will be shutdown after a while,
|
1662
|
-
as can be specified with <<PassengerPoolIdleTime,PassengerPoolIdleTime>> (unless this
|
1663
|
-
value is set to 0, in which case application instances are never shut down via idle
|
1664
|
-
time). The value of 'inactive' equals `count - active`.
|
1665
|
-
|
1666
|
-
The 'domains' section shows, for each application directory, information about running
|
1667
|
-
application instances:
|
1668
|
-
|
1669
|
-
Sessions:: Shows how many HTTP client are currently in the queue of that application
|
1670
|
-
Instance, waiting to be processed.
|
1671
|
-
Processed:: Indicates how many requests the instance has served until now. *Tip:* it's
|
1672
|
-
possible to limit this number with the <<PassengerMaxRequests,PassengerMaxRequests>>
|
1673
|
-
configuration directive.
|
1674
|
-
Uptime:: Shows for how long the application instance has been running.
|
1675
|
-
|
1676
|
-
Since Phusion Passenger uses fair load balancing by default, the number of sessions for the
|
1677
|
-
application instances should be fairly close to each other. For example, this is fairly
|
1678
|
-
normal:
|
1679
|
-
--------------------------------
|
1680
|
-
PID: 4281 Sessions: 2 Processed: 7 Uptime: 5m 11s
|
1681
|
-
PID: 4268 Sessions: 0 Processed: 5 Uptime: 4m 52s
|
1682
|
-
PID: 4265 Sessions: 1 Processed: 6 Uptime: 5m 38s
|
1683
|
-
PID: 4275 Sessions: 1 Processed: 7 Uptime: 3m 14s
|
1684
|
-
--------------------------------
|
1685
|
-
|
1686
|
-
But if you see a "spike", i.e. an application instance has an unusually high number of
|
1687
|
-
sessions compared to the others, then there might be a problem:
|
1688
|
-
--------------------------------
|
1689
|
-
PID: 4281 Sessions: 2 Processed: 7 Uptime: 5m 11s
|
1690
|
-
PID: 17468 Sessions: 8 <-+ Processed: 2 Uptime: 4m 47s
|
1691
|
-
PID: 4265 Sessions: 1 | Processed: 6 Uptime: 5m 38s
|
1692
|
-
PID: 4275 Sessions: 1 | Processed: 7 Uptime: 3m 14s
|
1693
|
-
|
|
1694
|
-
+---- "spike"
|
1695
|
-
--------------------------------
|
1696
|
-
|
1697
|
-
Possible reasons why spikes can occur:
|
1698
|
-
|
1699
|
-
. Your application is busy processing a request that takes a very long time.
|
1700
|
-
If this is the case, then you might want to turn
|
1701
|
-
<<PassengerUseGlobalQueue,global queuing>> on.
|
1702
|
-
. Your application is frozen, i.e. has stopped responding. See
|
1703
|
-
<<debugging_frozen,Debugging frozen applications>> for tips.
|
1704
|
-
|
1705
|
-
|
1706
|
-
[[debugging_frozen]]
|
1707
|
-
=== Debugging frozen applications ===
|
1708
|
-
|
1709
|
-
If one of your application instances is frozen (stopped responding), then you
|
1710
|
-
can figure out where it is frozen by killing it with 'SIGABRT'. This will cause the
|
1711
|
-
application to raise an exception, with a backtrace.
|
1712
|
-
|
1713
|
-
The exception (with full backtrace information) is normally logged into the Apache
|
1714
|
-
error log. But if your application or if its web framework has its own exception logging
|
1715
|
-
routines, then exceptions might be logged into the application's log files instead.
|
1716
|
-
This is the case with Ruby on Rails. So if you kill a Ruby on Rails application with
|
1717
|
-
'SIGABRT', please check the application's 'production.log' first (assuming that you're
|
1718
|
-
running it in a 'production' environment). If you don't see a backtrace there, check
|
1719
|
-
the Apache error log.
|
1720
|
-
|
1721
|
-
NOTE: It is safe to kill application instances, even in live environments. Phusion Passenger
|
1722
|
-
will restart killed application instances, as if nothing bad happened.
|
1402
|
+
include::users_guide_snippets/analysis_and_system_maintenance_tools.txt[]
|
1723
1403
|
|
1724
1404
|
|
1725
1405
|
== Tips ==
|
1726
1406
|
|
1727
|
-
[
|
1728
|
-
=== User switching (security) ===
|
1729
|
-
|
1730
|
-
There is a problem that plagues most PHP web hosts, namely the fact that all PHP
|
1731
|
-
applications are run in the same user context as the web server. So for
|
1732
|
-
example, Joe's PHP application will be able to read Jane's PHP application's
|
1733
|
-
passwords. This is obviously undesirable on many servers.
|
1734
|
-
|
1735
|
-
Phusion Passenger solves this problem by implementing 'user switching'. A Rails
|
1736
|
-
application is started as the owner of the file 'config/environment.rb',
|
1737
|
-
and a Rack application is started as the owner of the file 'config.ru'.
|
1738
|
-
So if '/home/webapps/foo/config/environment.rb' is owned by 'joe', then Phusion
|
1739
|
-
Passenger will launch the corresponding Rails application as 'joe' as well.
|
1740
|
-
|
1741
|
-
This behavior is the default, and you don't need to configure anything. But
|
1742
|
-
there are things that you should keep in mind:
|
1743
|
-
|
1744
|
-
- The owner of 'environment.rb' must have read access to the Rails application's
|
1745
|
-
folder, and read/write access to the Rails application's 'logs' folder.
|
1746
|
-
Likewise, the owner of 'config.ru' must have read access to the Rack application's
|
1747
|
-
folder.
|
1748
|
-
- This feature is only available if Apache is started by 'root'. This is the
|
1749
|
-
case on most Apache installations.
|
1750
|
-
- Under no circumstances will applications be run as 'root'. If
|
1751
|
-
'environment.rb'/'config.ru' is owned as root or by an unknown user, then the
|
1752
|
-
Rails/Rack application will run as the user specified by
|
1753
|
-
<<PassengerDefaultUser,PassengerDefaultUser>>.
|
1754
|
-
|
1755
|
-
User switching can be disabled with the
|
1756
|
-
<<PassengerUserSwitching,PassengerUserSwitching>> option.
|
1757
|
-
|
1758
|
-
|
1759
|
-
[[reducing_memory_usage]]
|
1760
|
-
=== Reducing memory consumption of Ruby on Rails applications by 33% ===
|
1761
|
-
|
1762
|
-
Is it possible to reduce memory consumption of your Rails applications by 33% on average,
|
1763
|
-
by using http://www.rubyenterpriseedition.com/[Ruby Enterprise Edition].
|
1764
|
-
Please visit the website for details.
|
1765
|
-
|
1766
|
-
Note that this feature does not apply to Rack applications.
|
1767
|
-
|
1768
|
-
[[capistrano]]
|
1769
|
-
=== Capistrano recipe ===
|
1770
|
-
|
1771
|
-
Phusion Passenger can be combined with link:http://capify.org/[Capistrano].
|
1772
|
-
The following Capistrano recipe demonstrates Phusion Passenger support.
|
1773
|
-
It assumes that you're using Git as version control system.
|
1774
|
-
|
1775
|
-
--------------------------------------------------
|
1776
|
-
set :application, "myapp"
|
1777
|
-
set :domain, "example.com"
|
1778
|
-
set :repository, "ssh://#{domain}/path-to-your-git-repo/#{application}.git"
|
1779
|
-
set :use_sudo, false
|
1780
|
-
set :deploy_to, "/path-to-your-web-app-directory/#{application}"
|
1781
|
-
set :scm, "git"
|
1782
|
-
|
1783
|
-
role :app, domain
|
1784
|
-
role :web, domain
|
1785
|
-
role :db, domain, :primary => true
|
1786
|
-
|
1787
|
-
namespace :deploy do
|
1788
|
-
task :start, :roles => :app do
|
1789
|
-
run "touch #{current_release}/tmp/restart.txt"
|
1790
|
-
end
|
1791
|
-
|
1792
|
-
task :stop, :roles => :app do
|
1793
|
-
# Do nothing.
|
1794
|
-
end
|
1795
|
-
|
1796
|
-
desc "Restart Application"
|
1797
|
-
task :restart, :roles => :app do
|
1798
|
-
run "touch #{current_release}/tmp/restart.txt"
|
1799
|
-
end
|
1800
|
-
end
|
1801
|
-
--------------------------------------------------
|
1802
|
-
|
1803
|
-
You may notice that after each deploy, a new spawner server is
|
1804
|
-
created (it'll show up in `passenger-memory-stats`). Indeed, Capistrano will deploy
|
1805
|
-
to a path ending with '/current' (ie : '/u/apps/yourapp/current'), so that you don't
|
1806
|
-
have to care about revisions in your virtual host configuration. This '/current' directory
|
1807
|
-
is a symlink to the current revision deployed ('/path_to_app/releases/date_of_the_release').
|
1808
|
-
Phusion Passenger recognizes applications by their full canonical path, so after
|
1809
|
-
deploying a new version, Phusion Passenger will think that the new version is
|
1810
|
-
a totally different application, thereby creating a new spawner server:
|
1811
|
-
|
1812
|
-
--------------------------------------------------
|
1813
|
-
1001 30291 [...] Passenger ApplicationSpawner: /u/apps/my_app/releases/20080509104413
|
1814
|
-
1001 31371 [...] Passenger ApplicationSpawner: /u/apps/my_app/releases/20080509104632
|
1815
|
-
--------------------------------------------------
|
1816
|
-
|
1817
|
-
Don't worry about this. The (old) spawner server will terminate itself after its
|
1818
|
-
timeout period (10 minutes by default), so you will not run out of memory.
|
1819
|
-
|
1820
|
-
If you really want to release the spawner server's memory immediately, then you can add a command
|
1821
|
-
to your Capistrano script to terminate the Passenger spawn server after each deploy. That
|
1822
|
-
command is as follows:
|
1823
|
-
|
1824
|
-
--------------------------------------------------
|
1825
|
-
kill $( passenger-memory-stats | grep 'Passenger spawn server' | awk '{ print $1 }' )
|
1826
|
-
--------------------------------------------------
|
1827
|
-
|
1828
|
-
Killing the spawn server is completely safe, because Phusion Passenger will restart the
|
1829
|
-
spawn server if it has been terminated.
|
1830
|
-
|
1831
|
-
|
1832
|
-
=== Moving Phusion Passenger to a different directory ===
|
1833
|
-
|
1834
|
-
It is possible to relocate the Phusion Passenger files to a different directory. It
|
1835
|
-
involves two steps:
|
1836
|
-
|
1837
|
-
1. Moving the directory.
|
1838
|
-
2. Updating the ``PassengerRoot'' configuration option in Apache.
|
1839
|
-
|
1840
|
-
For example, if Phusion Passenger is located in '/opt/passenger/', and you'd like to
|
1841
|
-
move it to '/usr/local/passenger/', then do this:
|
1842
|
-
|
1843
|
-
1. Run the following command:
|
1844
|
-
+
|
1845
|
-
------------------------------------
|
1846
|
-
mv /opt/passenger /usr/local/passenger
|
1847
|
-
------------------------------------
|
1848
|
-
2. Edit your Apache configuration file, and set:
|
1849
|
-
+
|
1850
|
-
------------------------------------
|
1851
|
-
PassengerRoot /usr/local/passenger
|
1852
|
-
------------------------------------
|
1853
|
-
|
1854
|
-
=== Installing multiple Ruby on Rails versions ===
|
1855
|
-
|
1856
|
-
Each Ruby on Rails applications that are going to be deployed may require a
|
1857
|
-
specific Ruby on Rails version. You can install a specific version with
|
1858
|
-
this command:
|
1859
|
-
-----------------------------
|
1860
|
-
gem install rails -v X.X.X
|
1861
|
-
-----------------------------
|
1862
|
-
where 'X.X.X' is the version number of Ruby on Rails.
|
1863
|
-
|
1864
|
-
All of these versions will exist in parallel, and will not conflict with each
|
1865
|
-
other. Phusion Passenger will automatically make use of the correct version.
|
1407
|
+
include::users_guide_snippets/tips.txt[]
|
1866
1408
|
|
1867
1409
|
=== X-Sendfile support ===
|
1868
1410
|
|
@@ -1875,447 +1417,9 @@ Phusion Passenger does not provide upload progress support by itself. Please
|
|
1875
1417
|
try drogus's link:http://github.com/drogus/apache-upload-progress-module/tree/master[
|
1876
1418
|
Apache upload progress module] instead.
|
1877
1419
|
|
1878
|
-
=== Making the application restart after each request ===
|
1879
|
-
|
1880
|
-
In some situations it might be desirable to restart the web application after
|
1881
|
-
each request, for example when developing a non-Rails application that doesn't
|
1882
|
-
support code reloading, or when developing a web framework.
|
1883
|
-
|
1884
|
-
To achieve this, simply create the file 'tmp/always_restart.txt' in your
|
1885
|
-
application's root folder. Unlike 'restart.txt', Phusion Passenger does not
|
1886
|
-
check for this file's timestamp: Phusion Passenger will always restart the
|
1887
|
-
application, as long as 'always_restart.txt' exists.
|
1888
|
-
|
1889
|
-
NOTE: If you're just developing a Rails application then you probably don't need
|
1890
|
-
this feature. If you set 'RailsEnv development' in your Apache configuration,
|
1891
|
-
then Rails will automatically reload your application code after each request.
|
1892
|
-
'always_restart.txt' is only useful if you're working on Ruby on Rails itself,
|
1893
|
-
or when you're not developing a Rails application and your web framework
|
1894
|
-
does not support code reloading.
|
1895
|
-
|
1896
|
-
[[sub_uri_deployment_uri_fix]]
|
1897
|
-
=== How to fix broken images/CSS/JavaScript URIs in sub-URI deployments
|
1898
|
-
|
1899
|
-
Some people experience broken images and other broken static assets when they
|
1900
|
-
deploy their application to a sub-URI (i.e. 'http://mysite.com/railsapp/').
|
1901
|
-
The reason for this usually is that you used a
|
1902
|
-
static URI for your image in the views. This means your 'img' source probably refers
|
1903
|
-
to something like '/images/foo.jpg'. The leading slash means that it's an absolute URI:
|
1904
|
-
you're telling the browser to always load 'http://mysite.com/images/foo.jpg' no
|
1905
|
-
matter what. The problem is that the image is actually at
|
1906
|
-
'http://mysite.com/railsapp/images/foo.jpg'. There are two ways to fix this.
|
1907
|
-
|
1908
|
-
The first way (not recommended) is to change your view templates to refer to
|
1909
|
-
'images/foo.jpg'. This is a relative URI: note the lack of a leading slash). What
|
1910
|
-
this does is making the path relative to the current URI. The problem is that if you
|
1911
|
-
use restful URIs, then your images will probably break again when you add a level to
|
1912
|
-
the URI.
|
1913
|
-
For example, when you're at 'http://mysite.com/railsapp' the browser will look for
|
1914
|
-
'http://mysite.com/railsapp/images/foo.jpg'. But when you're at
|
1915
|
-
'http://mysite.com/railsapp/controller'. the browser will look for
|
1916
|
-
'http://mysite.com/railsapp/controller/images/foo.jpg'.
|
1917
|
-
So relative URIs usually don't work well with layout templates.
|
1918
|
-
|
1919
|
-
The second and highly recommended way is to always use Rails helper methods to
|
1920
|
-
output tags for static assets. These helper methods automatically take care
|
1921
|
-
of prepending the base URI that you've deployed the application to. For images
|
1922
|
-
there is `image_tag`, for JavaScript there is `javascript_include_tag` and for
|
1923
|
-
CSS there is `stylesheet_link_tag`. In the above example you would simply remove
|
1924
|
-
the '<img>' HTML tag and replace it with inline Ruby like this:
|
1925
|
-
|
1926
|
-
---------------------------------------
|
1927
|
-
<%= image_tag("foo.jpg") %>
|
1928
|
-
---------------------------------------
|
1929
|
-
|
1930
|
-
This will generate the proper image tag to `$RAILS_ROOT/public/images/foo.jpg`
|
1931
|
-
so that your images will always work no matter what sub-URI you've deployed to.
|
1932
|
-
|
1933
|
-
These helper methods are more valuable than you may think. For example they also
|
1934
|
-
append a timestamp to the URI to better facilitate HTTP caching. For more information,
|
1935
|
-
please refer to
|
1936
|
-
link:http://api.rubyonrails.org/classes/ActionView/Helpers/AssetTagHelper.html[the Rails API docs].
|
1937
|
-
|
1938
|
-
|
1939
|
-
== Appendix A: About this document ==
|
1940
|
-
|
1941
|
-
The text of this document is licensed under the
|
1942
|
-
link:http://creativecommons.org/licenses/by-sa/3.0/[Creative Commons
|
1943
|
-
Attribution-Share Alike 3.0 Unported License].
|
1944
|
-
|
1945
|
-
image:images/by_sa.png[link="http://creativecommons.org/licenses/by-sa/3.0/"]
|
1946
|
-
|
1947
|
-
Phusion Passenger is brought to you by link:http://www.phusion.nl/[Phusion].
|
1948
|
-
|
1949
|
-
image:images/phusion_banner.png[link="http://www.phusion.nl/"]
|
1950
|
-
|
1951
|
-
Phusion Passenger is a trademark of Hongli Lai & Ninh Bui.
|
1952
|
-
|
1953
|
-
== Appendix B: Terminology ==
|
1954
|
-
|
1955
|
-
[[application_root]]
|
1956
|
-
=== Application root ===
|
1957
|
-
The root directory of an application that's served by Phusion Passenger.
|
1958
|
-
|
1959
|
-
In case of Ruby on Rails applications, this is the directory that contains
|
1960
|
-
'Rakefile', 'app/', 'config/', 'public/', etc. In other words, the directory
|
1961
|
-
pointed to by `RAILS_ROOT`. For example, take the following directory structure:
|
1962
|
-
|
1963
|
-
-----------------------------------------
|
1964
|
-
/apps/foo/ <------ This is the Rails application's application root!
|
1965
|
-
|
|
1966
|
-
+- app/
|
1967
|
-
| |
|
1968
|
-
| +- controllers/
|
1969
|
-
| |
|
1970
|
-
| +- models/
|
1971
|
-
| |
|
1972
|
-
| +- views/
|
1973
|
-
|
|
1974
|
-
+- config/
|
1975
|
-
| |
|
1976
|
-
| +- environment.rb
|
1977
|
-
| |
|
1978
|
-
| +- ...
|
1979
|
-
|
|
1980
|
-
+- public/
|
1981
|
-
| |
|
1982
|
-
| +- ...
|
1983
|
-
|
|
1984
|
-
+- ...
|
1985
|
-
-----------------------------------------
|
1986
|
-
|
1987
|
-
In case of Rack applications, this is the directory that contains 'config.ru'.
|
1988
|
-
For example, take the following directory structure:
|
1989
|
-
|
1990
|
-
-----------------------------------------
|
1991
|
-
/apps/bar/ <----- This is the Rack application's application root!
|
1992
|
-
|
|
1993
|
-
+- public/
|
1994
|
-
| |
|
1995
|
-
| +- ...
|
1996
|
-
|
|
1997
|
-
+- config.ru
|
1998
|
-
|
|
1999
|
-
+- ...
|
2000
|
-
-----------------------------------------
|
2001
|
-
|
2002
|
-
In case of Python (WSGI) applications, this is the directory that contains
|
2003
|
-
'passenger_wsgi.py'. For example, take the following directory structure:
|
2004
|
-
|
2005
|
-
-----------------------------------------
|
2006
|
-
/apps/baz/ <----- This is the WSGI application's application root!
|
2007
|
-
|
|
2008
|
-
+- public/
|
2009
|
-
| |
|
2010
|
-
| +- ...
|
2011
|
-
|
|
2012
|
-
+- passenger_wsgi.py
|
2013
|
-
|
|
2014
|
-
+- ...
|
2015
|
-
-----------------------------------------
|
2016
1420
|
|
1421
|
+
include::users_guide_snippets/appendix_a_about.txt[]
|
2017
1422
|
|
2018
|
-
[
|
2019
|
-
== Appendix C: Spawning methods explained ==
|
2020
|
-
|
2021
|
-
At its core, Phusion Passenger is an HTTP proxy and process manager. It spawns
|
2022
|
-
Ruby on Rails/Rack/WSGI worker processes (which may also be referred to as
|
2023
|
-
'backend processes'), and forwards incoming HTTP request to one of the worker
|
2024
|
-
processes.
|
2025
|
-
|
2026
|
-
While this may sound simple, there's not just one way to spawn worker processes.
|
2027
|
-
Let's go over the different spawning methods. For simplicity's sake, let's
|
2028
|
-
assume that we're only talking about Ruby on Rails applications.
|
2029
|
-
|
2030
|
-
=== The most straightforward and traditional way: conservative spawning ===
|
2031
|
-
|
2032
|
-
Phusion Passenger could create a new Ruby process, which will then load the
|
2033
|
-
Rails application along with the entire Rails framework. This process will then
|
2034
|
-
enter an request handling main loop.
|
2035
|
-
|
2036
|
-
This is the most straightforward way to spawn worker processes. If you're
|
2037
|
-
familiar with the Mongrel application server, then this approach is exactly
|
2038
|
-
what mongrel_cluster performs: it creates N worker processes, each which loads
|
2039
|
-
a full copy of the Rails application and the Rails framework in memory. The Thin
|
2040
|
-
application server employs pretty much the same approach.
|
2041
|
-
|
2042
|
-
Note that Phusion Passenger's version of conservative spawning differs slightly
|
2043
|
-
from mongrel_cluster. Mongrel_cluster creates entirely new Ruby processes. In
|
2044
|
-
programmers jargon, mongrel_cluster creates new Ruby processes by forking the
|
2045
|
-
current process and exec()-ing a new Ruby interpreter. Phusion Passenger on the
|
2046
|
-
other hand creates processes that reuse the already loaded Ruby interpreter. In
|
2047
|
-
programmers jargon, Phusion Passenger calls fork(), but not exec().
|
2048
|
-
|
2049
|
-
=== The smart spawning method ===
|
2050
|
-
|
2051
|
-
NOTE: Smart spawning is only available for Ruby on Rails applications, not for
|
2052
|
-
Rack applications or WSGI applications.
|
2053
|
-
|
2054
|
-
While conservative spawning works well, it's not as efficient as it could be
|
2055
|
-
because each worker process has its own private copy of the Rails application
|
2056
|
-
as well as the Rails framework. This wastes memory as well as startup time.
|
2057
|
-
|
2058
|
-
image:images/conservative_spawning.png[Worker processes and conservative spawning] +
|
2059
|
-
'Figure: Worker processes and conservative spawning. Each worker process has its
|
2060
|
-
own private copy of the application code and Rails framework code.'
|
2061
|
-
|
2062
|
-
It is possible to make the different worker processes share the memory occupied
|
2063
|
-
by application and Rails framework code, by utilizing so-called
|
2064
|
-
copy-on-write semantics of the virtual memory system on modern operating
|
2065
|
-
systems. As a side effect, the startup time is also reduced. This is technique
|
2066
|
-
is exploited by Phusion Passenger's 'smart' and 'smart-lv2' spawn methods.
|
2067
|
-
|
2068
|
-
==== How it works ====
|
2069
|
-
|
2070
|
-
When the 'smart-lv2' spawn method is being used, Phusion Passenger will first
|
2071
|
-
create a so-called 'ApplicationSpawner server' process. This process loads the
|
2072
|
-
entire Rails application along with the Rails framework, by loading
|
2073
|
-
'environment.rb'. Then, whenever Phusion Passenger needs a new worker process,
|
2074
|
-
it will instruct the ApplicationSpawner server to do so. The ApplicationSpawner
|
2075
|
-
server will create a worker new process
|
2076
|
-
that reuses the already loaded Rails application/framework. Creating a worker
|
2077
|
-
process through an already running ApplicationSpawner server is very fast, about
|
2078
|
-
10 times faster than loading the Rails application/framework from scratch. If
|
2079
|
-
the Ruby interpreter is copy-on-write friendly (that is, if you're running
|
2080
|
-
<<reducing_memory_usage,Ruby Enterprise Edition>>) then all created worker
|
2081
|
-
processes will share as much common
|
2082
|
-
memory as possible. That is, they will all share the same application and Rails
|
2083
|
-
framework code.
|
2084
|
-
|
2085
|
-
image:images/smart-lv2.png[] +
|
2086
|
-
'Figure: Worker processes and the smart-lv2 spawn method. All worker processes,
|
2087
|
-
as well as the ApplicationSpawner, share the same application code and Rails
|
2088
|
-
framework code.'
|
2089
|
-
|
2090
|
-
The 'smart' spawn method goes even further, by caching the Rails framework in
|
2091
|
-
another process called the 'FrameworkSpawner server'. This process only loads
|
2092
|
-
the Rails framework, not the application. When a FrameworkSpawner server is
|
2093
|
-
instructed to create a new worker process, it will create a new
|
2094
|
-
ApplicationSpawner to which the instruction will be delegated. All those
|
2095
|
-
ApplicationSpawner servers, as well as all worker processes created by those
|
2096
|
-
ApplicationSpawner servers, will share the same Rails framework code.
|
2097
|
-
|
2098
|
-
The 'smart-lv2' method allows different worker processes that belong to the same
|
2099
|
-
application to share memory. The 'smart' method allows different worker
|
2100
|
-
processes - that happen to use the same Rails version - to share memory, even if
|
2101
|
-
they don't belong to the same application.
|
2102
|
-
|
2103
|
-
Notes:
|
2104
|
-
|
2105
|
-
- Vendored Rails frameworks cannot be shared by different applications, even if
|
2106
|
-
both vendored Rails frameworks are the same version. So for efficiency reasons
|
2107
|
-
we don't recommend vendoring Rails.
|
2108
|
-
- ApplicationSpawner and FrameworkSpawner servers have an idle timeout just
|
2109
|
-
like worker processes. If an ApplicationSpawner/FrameworkSpawner server hasn't
|
2110
|
-
been instructed to do anything for a while, it will be shutdown in order to
|
2111
|
-
conserve memory. This idle timeout is configurable.
|
2112
|
-
|
2113
|
-
==== Summary of benefits ====
|
2114
|
-
|
2115
|
-
Suppose that Phusion Passenger needs a new worker process for an application
|
2116
|
-
that uses Rails 2.2.1.
|
2117
|
-
|
2118
|
-
- If the 'smart-lv2' spawning method is used, and an ApplicationSpawner server
|
2119
|
-
for this application is already running, then worker process creation time is
|
2120
|
-
about 10 times faster than conservative spawning. This worker process will also
|
2121
|
-
share application and Rails framework code memory with the ApplicationSpawner
|
2122
|
-
server and the worker processes that had been spawned by this ApplicationSpawner
|
2123
|
-
server.
|
2124
|
-
- If the 'smart' spawning method is used, and a FrameworkSpawner server for
|
2125
|
-
Rails 2.2.1 is already running, but no ApplicationSpawner server for this
|
2126
|
-
application is running, then worker process creation time is about 2 times
|
2127
|
-
faster than conservative spawning. If there is an ApplicationSpawner server
|
2128
|
-
for this application running, then worker process creation time is about 10
|
2129
|
-
times faster. This worker process will also share application and Rails
|
2130
|
-
framework code memory with the ApplicationSpawner and FrameworkSpawner
|
2131
|
-
servers.
|
2132
|
-
|
2133
|
-
You could compare ApplicationSpawner and FrameworkSpawner servers with stem
|
2134
|
-
cells, that have the ability to quickly change into more specific cells (worker
|
2135
|
-
process).
|
2136
|
-
|
2137
|
-
In practice, the smart spawning methods could mean a memory saving of about 33%,
|
2138
|
-
assuming that your Ruby interpreter is <<reducing_memory_usage,copy-on-write friendly>>.
|
2139
|
-
|
2140
|
-
Of course, smart spawning is not without gotchas. But if you understand the
|
2141
|
-
gotchas you can easily reap the benefits of smart spawning.
|
2142
|
-
|
2143
|
-
=== Smart spawning gotcha #1: unintential file descriptor sharing ===
|
2144
|
-
|
2145
|
-
Because worker processes are created by forking from an ApplicationSpawner
|
2146
|
-
server, it will share all file descriptors that are opened by the
|
2147
|
-
ApplicationSpawner server. (This is part of the semantics of the Unix
|
2148
|
-
'fork()' system call. You might want to Google it if you're not familiar with
|
2149
|
-
it.) A file descriptor is a handle which can be an opened file, an opened socket
|
2150
|
-
connection, a pipe, etc. If different worker processes write to such a file
|
2151
|
-
descriptor at the same time, then their write calls will be interleaved, which
|
2152
|
-
may potentially cause problems.
|
2153
|
-
|
2154
|
-
The problem commonly involves socket connections that are unintentially being
|
2155
|
-
shared. You can fix it by closing and reestablishing the connection when Phusion
|
2156
|
-
Passenger is creating a new worker process. Phusion Passenger provides the API
|
2157
|
-
call `PhusionPassenger.on_event(:starting_worker_process)` to do so. So you
|
2158
|
-
could insert the following code in your 'environment.rb':
|
2159
|
-
|
2160
|
-
[source, ruby]
|
2161
|
-
-----------------------------------------
|
2162
|
-
if defined?(PhusionPassenger)
|
2163
|
-
PhusionPassenger.on_event(:starting_worker_process) do |forked|
|
2164
|
-
if forked
|
2165
|
-
# We're in smart spawning mode.
|
2166
|
-
... code to reestablish socket connections here ...
|
2167
|
-
else
|
2168
|
-
# We're in conservative spawning mode. We don't need to do anything.
|
2169
|
-
end
|
2170
|
-
end
|
2171
|
-
end
|
2172
|
-
-----------------------------------------
|
2173
|
-
|
2174
|
-
Note that Phusion Passenger automatically reestablishes the connection to the
|
2175
|
-
database upon creating a new worker process, which is why you normally do not
|
2176
|
-
encounter any database issues when using smart spawning mode.
|
2177
|
-
|
2178
|
-
==== Example 1: Memcached connection sharing (harmful) ====
|
2179
|
-
|
2180
|
-
Suppose we have a Rails application that connects to a Memcached server in
|
2181
|
-
'environment.rb'. This causes the ApplicationSpawner to have a socket connection
|
2182
|
-
(file descriptor) to the Memcached server, as shown in the following figure:
|
2183
|
-
|
2184
|
-
+--------------------+
|
2185
|
-
| ApplicationSpawner |-----------[Memcached server]
|
2186
|
-
+--------------------+
|
2187
|
-
|
2188
|
-
Phusion Passenger then proceeds with creating a new Rails worker process, which
|
2189
|
-
is to process incoming HTTP requests. The result will look like this:
|
2190
|
-
|
2191
|
-
+--------------------+
|
2192
|
-
| ApplicationSpawner |------+----[Memcached server]
|
2193
|
-
+--------------------+ |
|
2194
|
-
|
|
2195
|
-
+--------------------+ |
|
2196
|
-
| Worker process 1 |-----/
|
2197
|
-
+--------------------+
|
2198
|
-
|
2199
|
-
Since a 'fork()' makes a (virtual) complete copy of a process, all its file
|
2200
|
-
descriptors will be copied as well. What we see here is that ApplicationSpawner
|
2201
|
-
and Worker process 1 both share the same connection to Memcached.
|
2202
|
-
|
2203
|
-
Now supposed that your site gets Slashdotted and Phusion Passenger needs to
|
2204
|
-
spawn another worker process. It does so by forking ApplicationSpawner. The
|
2205
|
-
result is now as follows:
|
2206
|
-
|
2207
|
-
+--------------------+
|
2208
|
-
| ApplicationSpawner |------+----[Memcached server]
|
2209
|
-
+--------------------+ |
|
2210
|
-
|
|
2211
|
-
+--------------------+ |
|
2212
|
-
| Worker process 1 |-----/|
|
2213
|
-
+--------------------+ |
|
2214
|
-
|
|
2215
|
-
+--------------------+ |
|
2216
|
-
| Worker process 2 |-----/
|
2217
|
-
+--------------------+
|
2218
|
-
|
2219
|
-
As you can see, Worker process 1 and Worker process 2 have the same Memcache
|
2220
|
-
connection.
|
2221
|
-
|
2222
|
-
Suppose that users Joe and Jane visit your website at the same time. Joe's
|
2223
|
-
request is handled by Worker process 1, and Jane's request is handled by Worker
|
2224
|
-
process 2. Both worker processes want to fetch something from Memcached. Suppose
|
2225
|
-
that in order to do that, both handlers need to send a "FETCH" command to Memcached.
|
2226
|
-
|
2227
|
-
But suppose that, after worker process 1 having only sent "FE", a context switch
|
2228
|
-
occurs, and worker process 2 starts sending a "FETCH" command to Memcached as
|
2229
|
-
well. If worker process 2 succeeds in sending only one bye, 'F', then Memcached
|
2230
|
-
will receive a command which begins with "FEF", a command that it does not
|
2231
|
-
recognize. In other words: the data from both handlers get interleaved. And thus
|
2232
|
-
Memcached is forced to handle this as an error.
|
2233
|
-
|
2234
|
-
This problem can be solved by reestablishing the connection to Memcached after forking:
|
2235
|
-
|
2236
|
-
+--------------------+
|
2237
|
-
| ApplicationSpawner |------+----[Memcached server]
|
2238
|
-
+--------------------+ | |
|
2239
|
-
| |
|
2240
|
-
+--------------------+ | |
|
2241
|
-
| Worker process 1 |-----/| |
|
2242
|
-
+--------------------+ | | <--- created this
|
2243
|
-
X | new
|
2244
|
-
| connection
|
2245
|
-
X <-- closed this |
|
2246
|
-
+--------------------+ | old |
|
2247
|
-
| Worker process 2 |-----/ connection |
|
2248
|
-
+--------------------+ |
|
2249
|
-
| |
|
2250
|
-
+-------------------------------------+
|
2251
|
-
|
2252
|
-
Worker process 2 now has its own, separate communication channel with Memcached.
|
2253
|
-
The code in 'environment.rb' looks like this:
|
2254
|
-
|
2255
|
-
[source, ruby]
|
2256
|
-
-----------------------------------------
|
2257
|
-
if defined?(PhusionPassenger)
|
2258
|
-
PhusionPassenger.on_event(:starting_worker_process) do |forked|
|
2259
|
-
if forked
|
2260
|
-
# We're in smart spawning mode.
|
2261
|
-
reestablish_connection_to_memcached
|
2262
|
-
else
|
2263
|
-
# We're in conservative spawning mode. We don't need to do anything.
|
2264
|
-
end
|
2265
|
-
end
|
2266
|
-
end
|
2267
|
-
-----------------------------------------
|
2268
|
-
|
2269
|
-
==== Example 2: Log file sharing (not harmful) ====
|
2270
|
-
|
2271
|
-
There are also cases in which unintential file descriptor sharing is not harmful.
|
2272
|
-
One such case is log file file descriptor sharing. Even if two processes write
|
2273
|
-
to the log file at the same time, the worst thing that can happen is that the
|
2274
|
-
data in the log file is interleaved.
|
2275
|
-
|
2276
|
-
To guarantee that the data written to the log file is never interleaved, you
|
2277
|
-
must synchronize write access via an inter-process synchronization mechanism,
|
2278
|
-
such as file locks. Reopening the log file, like you would have done in the
|
2279
|
-
Memcached example, doesn't help.
|
2280
|
-
|
2281
|
-
=== Smart spawning gotcha #2: the need to revive threads ===
|
2282
|
-
|
2283
|
-
Another part of the 'fork()' system call's semantics is the fact that threads
|
2284
|
-
disappear after a fork call. So if you've created any threads in environment.rb,
|
2285
|
-
then those threads will no longer be running in newly created worker process.
|
2286
|
-
You need to revive them when a new worker process is created. Use the
|
2287
|
-
`:starting_worker_process` event that Phusion Passenger provides, like this:
|
2288
|
-
|
2289
|
-
[source, ruby]
|
2290
|
-
-----------------------------------------
|
2291
|
-
if defined?(PhusionPassenger)
|
2292
|
-
PhusionPassenger.on_event(:starting_worker_process) do |forked|
|
2293
|
-
if forked
|
2294
|
-
# We're in smart spawning mode.
|
2295
|
-
... code to revive threads here ...
|
2296
|
-
else
|
2297
|
-
# We're in conservative spawning mode. We don't need to do anything.
|
2298
|
-
end
|
2299
|
-
end
|
2300
|
-
end
|
2301
|
-
-----------------------------------------
|
1423
|
+
include::users_guide_snippets/appendix_b_terminology.txt[]
|
2302
1424
|
|
2303
|
-
|
2304
|
-
|
2305
|
-
This gotcha is only applicable to the 'smart' spawn method, not the 'smart-lv2'
|
2306
|
-
spawn method.
|
2307
|
-
|
2308
|
-
If your application expects the Rails framework to be not loaded during the
|
2309
|
-
beginning of 'environment.rb', then it can cause problems when an
|
2310
|
-
ApplicationSpawner is created from a FrameworkSpawner, which already has the
|
2311
|
-
Rails framework loaded. The most common case is when applications try to patch
|
2312
|
-
Rails by dropping a modified file that has the same name as Rails's own file,
|
2313
|
-
in a path that comes earlier in the Ruby search path.
|
2314
|
-
|
2315
|
-
For example, suppose that we have an application which has a patched version
|
2316
|
-
of 'active_record/base.rb' located in 'RAILS_ROOT/lib/patches', and
|
2317
|
-
'RAILS_ROOT/lib/patches' comes first in the Ruby load path. When conservative
|
2318
|
-
spawning is used, the patched version of 'base.rb' is properly loaded. When
|
2319
|
-
'smart' (not 'smart-lv2') spawning is used, the original 'base.rb' is used
|
2320
|
-
because it was already loaded, so a subsequent `require "active_record/base"`
|
2321
|
-
has no effect.
|
1425
|
+
include::users_guide_snippets/appendix_c_spawning_methods.txt[]
|