passenger 2.0.6 → 2.1.2
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 +10 -4
- data/LICENSE +1 -1
- data/NEWS +0 -0
- data/Rakefile +183 -117
- data/benchmark/dispatcher.rb +5 -9
- data/bin/passenger-install-apache2-module +52 -18
- data/bin/passenger-memory-stats +67 -13
- data/bin/passenger-spawn-server +8 -4
- data/bin/passenger-status +21 -46
- data/bin/passenger-stress-test +5 -5
- data/debian/postinst +1 -1
- data/doc/ApplicationPool algorithm.txt +180 -128
- data/doc/Architectural overview.html +1 -778
- data/doc/Security of user switching support.html +1 -643
- data/doc/Users guide Apache.html +3127 -0
- data/doc/Users guide Nginx.html +1458 -0
- data/doc/Users guide.html +1404 -467
- data/doc/Users guide.txt +843 -105
- data/doc/cxxapi/ApplicationPoolServer_8h-source.html +751 -641
- data/doc/cxxapi/ApplicationPool_8h-source.html +168 -171
- data/doc/cxxapi/Application_8h-source.html +494 -394
- data/doc/cxxapi/Bucket_8h-source.html +21 -15
- data/doc/cxxapi/CachedFileStat_8h-source.html +191 -0
- data/doc/cxxapi/Configuration_8h-source.html +311 -149
- data/doc/cxxapi/DirectoryMapper_8h-source.html +309 -0
- data/doc/cxxapi/DummySpawnManager_8h-source.html +3 -4
- data/doc/cxxapi/Exceptions_8h-source.html +182 -165
- data/doc/cxxapi/FileChecker_8h-source.html +130 -0
- data/doc/cxxapi/Hooks_8h-source.html +2 -3
- data/doc/cxxapi/Logging_8h-source.html +92 -89
- data/doc/cxxapi/MessageChannel_8h-source.html +585 -477
- data/doc/cxxapi/PoolOptions_8h-source.html +305 -0
- data/doc/cxxapi/SpawnManager_8h-source.html +515 -540
- data/doc/cxxapi/StandardApplicationPool_8h-source.html +779 -679
- data/doc/cxxapi/SystemTime_8h-source.html +104 -0
- data/doc/cxxapi/Utils_8h-source.html +331 -227
- data/doc/cxxapi/annotated.html +6 -7
- data/doc/cxxapi/classClient-members.html +1 -2
- data/doc/cxxapi/classClient.html +1 -2
- data/doc/cxxapi/classHooks-members.html +5 -2
- data/doc/cxxapi/classHooks.html +112 -2
- data/doc/cxxapi/classPassenger_1_1Application-members.html +2 -3
- data/doc/cxxapi/classPassenger_1_1Application.html +8 -9
- data/doc/cxxapi/classPassenger_1_1ApplicationPool-members.html +4 -4
- data/doc/cxxapi/classPassenger_1_1ApplicationPool.html +42 -81
- data/doc/cxxapi/classPassenger_1_1ApplicationPoolServer-members.html +1 -2
- data/doc/cxxapi/classPassenger_1_1ApplicationPoolServer.html +3 -4
- data/doc/cxxapi/classPassenger_1_1ApplicationPool__inherit__graph.png +0 -0
- data/doc/cxxapi/classPassenger_1_1Application_1_1Session-members.html +3 -2
- data/doc/cxxapi/classPassenger_1_1Application_1_1Session.html +74 -3
- data/doc/cxxapi/classPassenger_1_1BusyException-members.html +1 -2
- data/doc/cxxapi/classPassenger_1_1BusyException.html +2 -3
- data/doc/cxxapi/classPassenger_1_1ConfigurationException-members.html +1 -2
- data/doc/cxxapi/classPassenger_1_1ConfigurationException.html +2 -3
- data/doc/cxxapi/classPassenger_1_1DirectoryMapper-members.html +38 -0
- data/doc/cxxapi/classPassenger_1_1DirectoryMapper.html +256 -0
- data/doc/cxxapi/classPassenger_1_1DummySpawnManager-members.html +1 -2
- data/doc/cxxapi/classPassenger_1_1DummySpawnManager.html +2 -3
- data/doc/cxxapi/{classPassenger_1_1Thread-members.html → classPassenger_1_1FileChecker-members.html} +4 -5
- data/doc/cxxapi/classPassenger_1_1FileChecker.html +121 -0
- data/doc/cxxapi/classPassenger_1_1FileNotFoundException-members.html +1 -2
- data/doc/cxxapi/classPassenger_1_1FileNotFoundException.html +2 -3
- data/doc/cxxapi/classPassenger_1_1FileNotFoundException__inherit__graph.png +0 -0
- data/doc/cxxapi/classPassenger_1_1FileSystemException-members.html +2 -3
- data/doc/cxxapi/classPassenger_1_1FileSystemException.html +2 -3
- data/doc/cxxapi/classPassenger_1_1FileSystemException__inherit__graph.png +0 -0
- data/doc/cxxapi/classPassenger_1_1IOException-members.html +1 -2
- data/doc/cxxapi/classPassenger_1_1IOException.html +2 -3
- data/doc/cxxapi/classPassenger_1_1IOException__inherit__graph.png +0 -0
- data/doc/cxxapi/classPassenger_1_1MessageChannel-members.html +5 -2
- data/doc/cxxapi/classPassenger_1_1MessageChannel.html +155 -5
- data/doc/cxxapi/{classboost_1_1this__thread_1_1enable__syscall__interruption-members.html → classPassenger_1_1RuntimeException-members.html} +2 -3
- data/doc/cxxapi/{classboost_1_1this__thread_1_1enable__syscall__interruption.html → classPassenger_1_1RuntimeException.html} +10 -8
- data/doc/cxxapi/classPassenger_1_1SpawnException-members.html +1 -2
- data/doc/cxxapi/classPassenger_1_1SpawnException.html +2 -3
- data/doc/cxxapi/classPassenger_1_1SpawnManager-members.html +2 -3
- data/doc/cxxapi/classPassenger_1_1SpawnManager.html +15 -56
- data/doc/cxxapi/classPassenger_1_1StandardApplicationPool-members.html +5 -4
- data/doc/cxxapi/classPassenger_1_1StandardApplicationPool.html +20 -81
- data/doc/cxxapi/classPassenger_1_1StandardApplicationPool__inherit__graph.png +0 -0
- data/doc/cxxapi/classPassenger_1_1SystemException-members.html +2 -3
- data/doc/cxxapi/classPassenger_1_1SystemException.html +9 -10
- data/doc/cxxapi/classPassenger_1_1SystemException__inherit__graph.png +0 -0
- data/doc/cxxapi/{classboost_1_1this__thread_1_1disable__syscall__interruption-members.html → classPassenger_1_1SystemTime-members.html} +5 -3
- data/doc/cxxapi/classPassenger_1_1SystemTime.html +86 -0
- data/doc/cxxapi/classPassenger_1_1TempFile-members.html +2 -3
- data/doc/cxxapi/classPassenger_1_1TempFile.html +17 -9
- data/doc/cxxapi/definitions_8h-source.html +1 -2
- data/doc/cxxapi/files.html +6 -3
- data/doc/cxxapi/functions.html +98 -35
- data/doc/cxxapi/functions_func.html +60 -32
- data/doc/cxxapi/functions_type.html +1 -2
- data/doc/cxxapi/functions_vars.html +27 -2
- data/doc/cxxapi/graph_legend.html +1 -2
- data/doc/cxxapi/graph_legend.png +0 -0
- data/doc/cxxapi/group__Configuration.html +3 -4
- data/doc/cxxapi/group__Configuration.png +0 -0
- data/doc/cxxapi/group__Core.html +3 -4
- data/doc/cxxapi/group__Core.png +0 -0
- data/doc/cxxapi/group__Exceptions.html +4 -2
- data/doc/cxxapi/group__Hooks.html +1 -6
- data/doc/cxxapi/group__Hooks.png +0 -0
- data/doc/cxxapi/group__Support.html +259 -36
- data/doc/cxxapi/hierarchy.html +6 -7
- 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 +2 -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 -1
- 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 +1 -2
- 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.png +0 -0
- data/doc/cxxapi/inherit__graph__18.png +0 -0
- 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 +1 -1
- 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 +2 -1
- 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 +1 -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 -2
- data/doc/cxxapi/inherit__graph__9.md5 +1 -1
- data/doc/cxxapi/inherit__graph__9.png +0 -0
- data/doc/cxxapi/inherits.html +30 -31
- data/doc/cxxapi/main.html +1 -2
- data/doc/cxxapi/modules.html +1 -2
- data/doc/cxxapi/structPassenger_1_1AnythingToString-members.html +1 -2
- data/doc/cxxapi/structPassenger_1_1AnythingToString.html +2 -3
- data/doc/cxxapi/structPassenger_1_1AnythingToString_3_01vector_3_01string_01_4_01_4-members.html +1 -2
- data/doc/cxxapi/structPassenger_1_1AnythingToString_3_01vector_3_01string_01_4_01_4.html +2 -3
- data/doc/cxxapi/structPassenger_1_1PoolOptions-members.html +49 -0
- data/doc/cxxapi/structPassenger_1_1PoolOptions.html +404 -0
- data/doc/cxxapi/tree.html +18 -20
- data/doc/images/conservative_spawning.png +0 -0
- data/doc/images/conservative_spawning.svg +248 -0
- data/doc/images/smart-lv2.png +0 -0
- data/doc/images/smart-lv2.svg +320 -0
- data/doc/rdoc/classes/ConditionVariable.html +68 -34
- data/doc/rdoc/classes/Exception.html +16 -16
- data/doc/rdoc/classes/GC.html +9 -9
- data/doc/rdoc/classes/IO.html +36 -17
- data/doc/rdoc/classes/PhusionPassenger.html +183 -0
- data/doc/rdoc/classes/PhusionPassenger/AbstractRequestHandler.html +511 -0
- data/doc/rdoc/classes/{Passenger → PhusionPassenger}/AbstractServer.html +285 -242
- data/doc/rdoc/classes/{Passenger → PhusionPassenger}/AbstractServer/ServerAlreadyStarted.html +3 -3
- data/doc/rdoc/classes/{Passenger → PhusionPassenger}/AbstractServer/ServerError.html +3 -3
- data/doc/rdoc/classes/{Passenger → PhusionPassenger}/AbstractServer/ServerNotStarted.html +3 -3
- data/doc/rdoc/classes/{Passenger → PhusionPassenger}/AbstractServer/UnknownMessage.html +3 -3
- data/doc/rdoc/classes/PhusionPassenger/AbstractServerCollection.html +598 -0
- data/doc/rdoc/classes/PhusionPassenger/AdminTools.html +140 -0
- data/doc/rdoc/classes/PhusionPassenger/AdminTools/ControlProcess.html +247 -0
- data/doc/rdoc/classes/PhusionPassenger/AdminTools/ControlProcess/Instance.html +138 -0
- data/doc/rdoc/classes/{Passenger → PhusionPassenger}/AppInitError.html +36 -19
- data/doc/rdoc/classes/{Passenger → PhusionPassenger}/Application.html +81 -96
- data/doc/rdoc/classes/{Passenger → PhusionPassenger}/ConsoleTextTemplate.html +18 -18
- data/doc/rdoc/classes/{Passenger → PhusionPassenger}/FrameworkInitError.html +20 -18
- data/doc/rdoc/classes/{Passenger → PhusionPassenger}/HTMLTemplate.html +18 -18
- data/doc/rdoc/classes/{Passenger → PhusionPassenger}/InitializationError.html +9 -9
- data/doc/rdoc/classes/PhusionPassenger/InvalidPath.html +92 -0
- data/doc/rdoc/classes/{Passenger → PhusionPassenger}/MessageChannel.html +93 -92
- data/doc/rdoc/classes/{Passenger → PhusionPassenger}/NativeSupport.html +55 -25
- data/doc/rdoc/classes/PhusionPassenger/Rack.html +91 -0
- data/doc/rdoc/classes/PhusionPassenger/Rack/ApplicationSpawner.html +185 -0
- data/doc/rdoc/classes/PhusionPassenger/Rack/RequestHandler.html +182 -0
- data/doc/rdoc/classes/PhusionPassenger/Railz.html +95 -0
- data/doc/rdoc/classes/PhusionPassenger/Railz/ApplicationSpawner.html +424 -0
- data/doc/rdoc/classes/PhusionPassenger/Railz/ApplicationSpawner/Error.html +98 -0
- data/doc/rdoc/classes/PhusionPassenger/Railz/CGIFixed.html +200 -0
- data/doc/rdoc/classes/PhusionPassenger/Railz/FrameworkSpawner.html +444 -0
- data/doc/rdoc/classes/PhusionPassenger/Railz/FrameworkSpawner/Error.html +98 -0
- data/doc/rdoc/classes/PhusionPassenger/Railz/RequestHandler.html +154 -0
- data/doc/rdoc/classes/PhusionPassenger/SpawnManager.html +408 -0
- data/doc/rdoc/classes/{Passenger → PhusionPassenger}/UnknownError.html +13 -13
- data/doc/rdoc/classes/PhusionPassenger/Utils.html +687 -0
- data/doc/rdoc/classes/{Passenger → PhusionPassenger}/VersionNotFound.html +8 -8
- data/doc/rdoc/classes/PhusionPassenger/WSGI.html +89 -0
- data/doc/rdoc/classes/PhusionPassenger/WSGI/ApplicationSpawner.html +188 -0
- data/doc/rdoc/classes/PlatformInfo.html +663 -159
- data/doc/rdoc/classes/RakeExtensions.html +4 -4
- data/doc/rdoc/classes/Signal.html +134 -0
- data/doc/rdoc/created.rid +1 -1
- data/doc/rdoc/files/DEVELOPERS_TXT.html +15 -10
- data/doc/rdoc/files/README.html +5 -7
- data/doc/rdoc/files/ext/{passenger → phusion_passenger}/native_support_c.html +2 -2
- data/doc/rdoc/files/lib/{passenger → phusion_passenger}/abstract_request_handler_rb.html +7 -9
- data/doc/rdoc/files/lib/phusion_passenger/abstract_server_collection_rb.html +120 -0
- data/doc/rdoc/files/lib/{passenger → phusion_passenger}/abstract_server_rb.html +7 -10
- data/doc/rdoc/files/lib/phusion_passenger/admin_tools/control_process_rb.html +99 -0
- data/doc/rdoc/files/lib/phusion_passenger/admin_tools_rb.html +92 -0
- data/doc/rdoc/files/lib/{passenger → phusion_passenger}/application_rb.html +6 -8
- data/doc/rdoc/files/lib/{passenger → phusion_passenger}/console_text_template_rb.html +5 -7
- data/doc/rdoc/files/lib/{passenger → phusion_passenger}/constants_rb.html +4 -5
- data/doc/rdoc/files/lib/{passenger → phusion_passenger}/dependencies_rb.html +6 -8
- data/doc/rdoc/files/lib/phusion_passenger/events_rb.html +116 -0
- data/doc/rdoc/files/lib/{passenger → phusion_passenger}/exceptions_rb.html +5 -7
- data/doc/rdoc/files/lib/{passenger → phusion_passenger}/html_template_rb.html +5 -7
- data/doc/rdoc/files/lib/{passenger → phusion_passenger}/message_channel_rb.html +5 -7
- data/doc/rdoc/files/lib/{passenger → phusion_passenger}/platform_info_rb.html +6 -7
- data/doc/rdoc/files/lib/phusion_passenger/rack/application_spawner_rb.html +123 -0
- data/doc/rdoc/files/lib/phusion_passenger/rack/request_handler_rb.html +117 -0
- data/doc/rdoc/files/lib/{passenger/utils_rb.html → phusion_passenger/railz/application_spawner_rb.html} +24 -17
- data/doc/rdoc/files/lib/phusion_passenger/railz/cgi_fixed_rb.html +126 -0
- data/doc/rdoc/files/lib/phusion_passenger/railz/framework_spawner_rb.html +139 -0
- data/doc/rdoc/files/lib/phusion_passenger/railz/request_handler_rb.html +118 -0
- data/doc/rdoc/files/lib/{passenger → phusion_passenger}/simple_benchmarking_rb.html +5 -7
- data/doc/rdoc/files/lib/{passenger → phusion_passenger}/spawn_manager_rb.html +40 -24
- data/doc/rdoc/files/lib/phusion_passenger/utils_rb.html +169 -0
- data/doc/rdoc/files/lib/phusion_passenger/wsgi/application_spawner_rb.html +120 -0
- data/doc/rdoc/files/lib/rake/extensions_rb.html +3 -4
- data/doc/rdoc/fr_class_index.html +37 -19
- data/doc/rdoc/fr_file_index.html +25 -14
- data/doc/rdoc/fr_method_index.html +145 -74
- data/ext/apache2/Application.h +145 -44
- data/ext/apache2/ApplicationPool.h +27 -29
- data/ext/apache2/ApplicationPoolServer.h +183 -72
- data/ext/apache2/ApplicationPoolServerExecutable.cpp +249 -42
- data/ext/apache2/Bucket.cpp +61 -9
- data/ext/apache2/Bucket.h +15 -8
- data/ext/apache2/CachedFileStat.cpp +114 -0
- data/ext/apache2/CachedFileStat.h +169 -0
- data/ext/apache2/Configuration.cpp +213 -22
- data/ext/apache2/Configuration.h +176 -13
- data/ext/apache2/DirectoryMapper.h +287 -0
- data/ext/apache2/Exceptions.h +30 -12
- data/ext/apache2/FileChecker.h +108 -0
- data/ext/apache2/Hooks.cpp +709 -493
- data/ext/apache2/LICENSE-CNRI.TXT +15 -0
- data/ext/apache2/Logging.h +26 -22
- data/ext/apache2/MessageChannel.h +124 -15
- data/ext/apache2/PoolOptions.h +283 -0
- data/ext/apache2/SpawnManager.h +75 -99
- data/ext/apache2/StandardApplicationPool.h +296 -195
- data/ext/apache2/SystemTime.cpp +28 -0
- data/ext/apache2/SystemTime.h +82 -0
- data/ext/apache2/Utils.cpp +172 -18
- data/ext/apache2/Utils.h +124 -19
- data/ext/boost/cstdint.hpp +4 -2
- data/ext/boost/current_function.hpp +67 -0
- data/ext/boost/detail/sp_counted_base.hpp +4 -4
- data/ext/boost/thread/exceptions.hpp +2 -1
- data/ext/boost/thread/pthread/thread.hpp +11 -3
- data/ext/boost/thread/pthread/thread_data.hpp +2 -1
- data/ext/oxt/backtrace.cpp +172 -0
- data/ext/oxt/backtrace.hpp +135 -0
- data/ext/oxt/detail/backtrace_disabled.hpp +39 -0
- data/ext/oxt/detail/backtrace_enabled.hpp +155 -0
- data/ext/oxt/detail/spin_lock_gcc_x86.hpp +82 -0
- data/ext/oxt/detail/spin_lock_portable.hpp +38 -0
- data/ext/oxt/detail/spin_lock_pthreads.hpp +97 -0
- data/ext/oxt/detail/tracable_exception_disabled.hpp +46 -0
- data/ext/oxt/detail/tracable_exception_enabled.hpp +48 -0
- data/ext/oxt/macros.hpp +58 -0
- data/ext/oxt/spin_lock.hpp +55 -0
- data/ext/{apache2/System.cpp → oxt/system_calls.cpp} +87 -52
- data/ext/oxt/system_calls.hpp +234 -0
- data/ext/oxt/thread.cpp +32 -0
- data/ext/oxt/thread.hpp +223 -0
- data/ext/oxt/tracable_exception.cpp +87 -0
- data/ext/oxt/tracable_exception.hpp +35 -0
- data/{lib/passenger/constants.rb → ext/phusion_passenger/extconf.rb} +14 -9
- data/ext/{passenger → phusion_passenger}/native_support.c +33 -6
- data/lib/{passenger → phusion_passenger}/abstract_request_handler.rb +209 -93
- data/lib/{passenger → phusion_passenger}/abstract_server.rb +23 -8
- data/lib/phusion_passenger/abstract_server_collection.rb +301 -0
- data/lib/phusion_passenger/admin_tools.rb +25 -0
- data/lib/phusion_passenger/admin_tools/control_process.rb +107 -0
- data/lib/{passenger → phusion_passenger}/application.rb +13 -16
- data/lib/{passenger → phusion_passenger}/console_text_template.rb +2 -2
- data/{ext/passenger/extconf.rb → lib/phusion_passenger/constants.rb} +5 -5
- data/lib/{passenger → phusion_passenger}/dependencies.rb +38 -32
- data/lib/phusion_passenger/events.rb +45 -0
- data/lib/{passenger → phusion_passenger}/exceptions.rb +12 -5
- data/lib/{passenger → phusion_passenger}/html_template.rb +2 -2
- data/lib/{passenger → phusion_passenger}/message_channel.rb +3 -2
- data/lib/phusion_passenger/platform_info.rb +500 -0
- data/lib/{passenger → phusion_passenger}/rack/application_spawner.rb +29 -22
- data/lib/{passenger → phusion_passenger}/rack/request_handler.rb +14 -9
- data/lib/{passenger → phusion_passenger}/railz/application_spawner.rb +94 -74
- data/lib/{passenger → phusion_passenger}/railz/cgi_fixed.rb +2 -2
- data/lib/{passenger → phusion_passenger}/railz/framework_spawner.rb +86 -98
- data/lib/{passenger → phusion_passenger}/railz/request_handler.rb +6 -6
- data/lib/{passenger → phusion_passenger}/simple_benchmarking.rb +0 -0
- data/lib/{passenger → phusion_passenger}/spawn_manager.rb +136 -128
- data/lib/{passenger → phusion_passenger}/templates/apache2_config_snippets.txt.erb +0 -0
- data/lib/{passenger → phusion_passenger}/templates/apache_must_be_compiled_with_compatible_mpm.txt.erb +0 -0
- data/lib/phusion_passenger/templates/app_exited_during_initialization.html.erb +38 -0
- data/lib/{passenger → phusion_passenger}/templates/app_init_error.html.erb +0 -0
- data/lib/{passenger → phusion_passenger}/templates/database_error.html.erb +0 -0
- data/lib/{passenger → phusion_passenger}/templates/deployment_example.txt.erb +1 -1
- data/lib/{passenger → phusion_passenger}/templates/error_layout.css +0 -0
- data/lib/{passenger → phusion_passenger}/templates/error_layout.html.erb +0 -0
- data/lib/{passenger → phusion_passenger}/templates/framework_init_error.html.erb +0 -0
- data/lib/{passenger → phusion_passenger}/templates/general_error.html.erb +0 -0
- data/lib/{passenger → phusion_passenger}/templates/invalid_app_root.html.erb +1 -1
- data/lib/{passenger → phusion_passenger}/templates/load_error.html.erb +0 -0
- data/lib/{passenger → phusion_passenger}/templates/no_write_permission_to_passenger_root.txt.erb +0 -0
- data/lib/{passenger → phusion_passenger}/templates/possible_solutions_for_compilation_and_installation_problems.txt.erb +0 -0
- data/lib/{passenger → phusion_passenger}/templates/run_installer_as_root.txt.erb +0 -0
- data/lib/{passenger → phusion_passenger}/templates/version_not_found.html.erb +0 -0
- data/lib/{passenger → phusion_passenger}/templates/welcome.txt.erb +0 -0
- data/lib/{passenger → phusion_passenger}/utils.rb +210 -44
- data/lib/{passenger → phusion_passenger}/wsgi/application_spawner.rb +18 -15
- data/lib/{passenger → phusion_passenger}/wsgi/request_handler.py +7 -1
- data/man/passenger-memory-stats.8 +1 -1
- data/misc/render_error_pages.rb +1 -1
- data/test/ApplicationPoolServerTest.cpp +0 -28
- data/test/ApplicationPoolServer_ApplicationPoolTest.cpp +4 -0
- data/test/ApplicationPoolTest.cpp +307 -69
- data/test/CachedFileStatTest.cpp +262 -0
- data/test/FileCheckerTest.cpp +79 -0
- data/test/MessageChannelTest.cpp +3 -3
- data/test/PoolOptionsTest.cpp +37 -0
- data/test/SpawnManagerTest.cpp +4 -4
- data/test/StandardApplicationPoolTest.cpp +4 -0
- data/test/SystemTimeTest.cpp +37 -0
- data/test/UtilsTest.cpp +137 -0
- data/test/integration_tests.rb +270 -23
- data/test/oxt/backtrace_test.cpp +128 -0
- data/test/oxt/oxt_test_main.cpp +25 -0
- data/test/oxt/syscall_interruption_test.cpp +50 -0
- data/test/ruby/abstract_request_handler_spec.rb +83 -0
- data/test/ruby/abstract_server_collection_spec.rb +246 -0
- data/test/ruby/application_spec.rb +3 -3
- data/test/ruby/message_channel_spec.rb +2 -2
- data/test/ruby/rack/application_spawner_spec.rb +3 -5
- data/test/ruby/rails/application_spawner_spec.rb +54 -15
- data/test/ruby/rails/framework_spawner_spec.rb +6 -8
- data/test/ruby/rails/minimal_spawner_spec.rb +29 -0
- data/test/ruby/rails/spawner_error_handling_spec.rb +1 -1
- data/test/ruby/rails/spawner_privilege_lowering_spec.rb +3 -3
- data/test/ruby/spawn_manager_spec.rb +23 -12
- data/test/ruby/utils_spec.rb +36 -2
- data/test/ruby/wsgi/application_spawner_spec.rb +47 -0
- data/test/stub/apache2/httpd.conf.erb +3 -5
- data/test/stub/message_channel.rb +2 -2
- data/test/stub/message_channel_2.rb +2 -2
- data/test/stub/message_channel_3.rb +3 -3
- data/test/stub/minimal-railsapp/README +0 -0
- data/test/stub/minimal-railsapp/config/application.rb +0 -0
- data/test/stub/minimal-railsapp/config/environment.rb +0 -0
- data/test/stub/minimal-railsapp/vendor/rails/actionmailer/lib/action_mailer.rb +0 -0
- data/test/stub/minimal-railsapp/vendor/rails/actionpack/lib/action_controller.rb +0 -0
- data/test/stub/minimal-railsapp/vendor/rails/actionpack/lib/action_pack.rb +0 -0
- data/test/stub/minimal-railsapp/vendor/rails/actionpack/lib/action_view.rb +0 -0
- data/test/stub/minimal-railsapp/vendor/rails/activerecord/lib/active_record.rb +0 -0
- data/test/stub/minimal-railsapp/vendor/rails/activeresource/lib/active_resource.rb +0 -0
- data/test/stub/minimal-railsapp/vendor/rails/activesupport/lib/active_support.rb +0 -0
- data/test/stub/minimal-railsapp/vendor/rails/activesupport/lib/active_support/whiny_nil.rb +0 -0
- data/test/stub/minimal-railsapp/vendor/rails/railties/lib/dispatcher.rb +0 -0
- data/test/stub/minimal-railsapp/vendor/rails/railties/lib/initializer.rb +0 -0
- data/test/stub/minimal-railsapp/vendor/rails/railties/lib/ruby_version_check.rb +0 -0
- data/test/stub/rails_apps/foobar/app/controllers/foo_controller.rb +8 -0
- data/test/stub/rails_apps/foobar/config/environments/development.rb +1 -2
- data/test/stub/rails_apps/mycook/app/controllers/welcome_controller.rb +21 -1
- data/test/stub/rails_apps/mycook/sites/some.site/public/uploads.html +26 -0
- data/test/stub/rails_apps/mycook/sites/some.site/public/welcome/cached.html +26 -0
- data/test/stub/railsapp/app/controllers/application.rb +0 -0
- data/test/stub/railsapp/app/controllers/bar_controller_1.rb +0 -0
- data/test/stub/railsapp/app/controllers/bar_controller_2.rb +1 -1
- data/test/stub/railsapp/app/controllers/foo_controller.rb +4 -0
- data/test/stub/railsapp/app/helpers/application_helper.rb +0 -0
- data/test/stub/railsapp/config/boot.rb +0 -0
- data/test/stub/railsapp/config/database.yml +0 -0
- data/test/stub/railsapp/config/environment.rb +0 -0
- data/test/stub/railsapp/config/environments/development.rb +0 -0
- data/test/stub/railsapp/config/environments/production.rb +0 -0
- data/test/stub/railsapp/config/initializers/inflections.rb +0 -0
- data/test/stub/railsapp/config/initializers/mime_types.rb +0 -0
- data/test/stub/railsapp/config/routes.rb +0 -0
- data/test/stub/railsapp/public/useless.txt +0 -0
- data/test/stub/spawn_server.rb +3 -4
- data/test/stub/wsgi/passenger_wsgi.pyc +0 -0
- data/test/support/apache2_controller.rb +57 -7
- data/test/support/tut.h +15 -0
- data/vendor/README +12 -0
- data/vendor/README_FOR_PACKAGERS +1 -0
- data/vendor/rack-0.9.1/AUTHORS +8 -0
- data/vendor/rack-0.9.1/COPYING +18 -0
- data/vendor/rack-0.9.1/ChangeLog +1423 -0
- data/vendor/rack-0.9.1/KNOWN-ISSUES +18 -0
- data/vendor/rack-0.9.1/README +306 -0
- data/vendor/rack-0.9.1/Rakefile +188 -0
- data/vendor/rack-0.9.1/SPEC +129 -0
- data/vendor/rack-0.9.1/lib/rack.rb +86 -0
- data/vendor/rack-0.9.1/lib/rack/adapter/camping.rb +22 -0
- data/vendor/rack-0.9.1/lib/rack/auth/abstract/handler.rb +28 -0
- data/vendor/rack-0.9.1/lib/rack/auth/abstract/request.rb +37 -0
- data/vendor/rack-0.9.1/lib/rack/auth/basic.rb +58 -0
- data/vendor/rack-0.9.1/lib/rack/auth/digest/md5.rb +124 -0
- data/vendor/rack-0.9.1/lib/rack/auth/digest/nonce.rb +51 -0
- data/vendor/rack-0.9.1/lib/rack/auth/digest/params.rb +55 -0
- data/vendor/rack-0.9.1/lib/rack/auth/digest/request.rb +40 -0
- data/vendor/rack-0.9.1/lib/rack/auth/openid.rb +438 -0
- data/vendor/rack-0.9.1/lib/rack/builder.rb +67 -0
- data/vendor/rack-0.9.1/lib/rack/cascade.rb +36 -0
- data/vendor/rack-0.9.1/lib/rack/commonlogger.rb +61 -0
- data/vendor/rack-0.9.1/lib/rack/conditionalget.rb +43 -0
- data/vendor/rack-0.9.1/lib/rack/content_length.rb +25 -0
- data/vendor/rack-0.9.1/lib/rack/deflater.rb +87 -0
- data/vendor/rack-0.9.1/lib/rack/directory.rb +150 -0
- data/vendor/rack-0.9.1/lib/rack/file.rb +85 -0
- data/vendor/rack-0.9.1/lib/rack/handler.rb +48 -0
- data/vendor/rack-0.9.1/lib/rack/handler/cgi.rb +57 -0
- data/vendor/rack-0.9.1/lib/rack/handler/evented_mongrel.rb +8 -0
- data/vendor/rack-0.9.1/lib/rack/handler/fastcgi.rb +86 -0
- data/vendor/rack-0.9.1/lib/rack/handler/lsws.rb +52 -0
- data/vendor/rack-0.9.1/lib/rack/handler/mongrel.rb +82 -0
- data/vendor/rack-0.9.1/lib/rack/handler/scgi.rb +57 -0
- data/vendor/rack-0.9.1/lib/rack/handler/swiftiplied_mongrel.rb +8 -0
- data/vendor/rack-0.9.1/lib/rack/handler/thin.rb +15 -0
- data/vendor/rack-0.9.1/lib/rack/handler/webrick.rb +61 -0
- data/vendor/rack-0.9.1/lib/rack/head.rb +19 -0
- data/vendor/rack-0.9.1/lib/rack/lint.rb +465 -0
- data/vendor/rack-0.9.1/lib/rack/lobster.rb +65 -0
- data/vendor/rack-0.9.1/lib/rack/methodoverride.rb +27 -0
- data/vendor/rack-0.9.1/lib/rack/mime.rb +204 -0
- data/vendor/rack-0.9.1/lib/rack/mock.rb +160 -0
- data/vendor/rack-0.9.1/lib/rack/recursive.rb +57 -0
- data/vendor/rack-0.9.1/lib/rack/reloader.rb +64 -0
- data/vendor/rack-0.9.1/lib/rack/request.rb +218 -0
- data/vendor/rack-0.9.1/lib/rack/response.rb +171 -0
- data/vendor/rack-0.9.1/lib/rack/session/abstract/id.rb +153 -0
- data/vendor/rack-0.9.1/lib/rack/session/cookie.rb +89 -0
- data/vendor/rack-0.9.1/lib/rack/session/memcache.rb +97 -0
- data/vendor/rack-0.9.1/lib/rack/session/pool.rb +73 -0
- data/vendor/rack-0.9.1/lib/rack/showexceptions.rb +348 -0
- data/vendor/rack-0.9.1/lib/rack/showstatus.rb +106 -0
- data/vendor/rack-0.9.1/lib/rack/static.rb +38 -0
- data/vendor/rack-0.9.1/lib/rack/urlmap.rb +48 -0
- data/vendor/rack-0.9.1/lib/rack/utils.rb +347 -0
- metadata +1197 -1055
- data/doc/cxxapi/System_8h-source.html +0 -251
- data/doc/cxxapi/classDirectoryMapper-members.html +0 -38
- data/doc/cxxapi/classDirectoryMapper.html +0 -203
- data/doc/cxxapi/classPassenger_1_1Thread.html +0 -100
- data/doc/cxxapi/classboost_1_1this__thread_1_1disable__syscall__interruption.html +0 -46
- data/doc/cxxapi/classboost_1_1this__thread_1_1restore__syscall__interruption-members.html +0 -33
- data/doc/cxxapi/classboost_1_1this__thread_1_1restore__syscall__interruption.html +0 -44
- data/doc/cxxapi/namespacePassenger.html +0 -208
- data/doc/cxxapi/namespacePassenger_1_1InterruptableCalls.html +0 -43
- data/doc/cxxapi/namespacemembers.html +0 -70
- data/doc/cxxapi/namespacemembers_func.html +0 -66
- data/doc/cxxapi/namespacemembers_type.html +0 -46
- data/doc/cxxapi/namespaces.html +0 -35
- data/doc/rdoc/classes/Passenger.html +0 -136
- data/doc/rdoc/classes/Passenger/AbstractRequestHandler.html +0 -402
- data/doc/rdoc/classes/Passenger/SpawnManager.html +0 -379
- data/doc/rdoc/classes/Passenger/Utils.html +0 -578
- data/ext/apache2/System.h +0 -228
- data/lib/passenger/platform_info.rb +0 -302
- data/lib/passenger/templates/app_exited_during_initialization.html.erb +0 -19
- data/test/stub/apache2/httpd.conf +0 -75
- data/test/stub/rails_apps/foobar/config/environments/test.rb +0 -22
- data/test/stub/rails_apps/mycook/config/environments/test.rb +0 -22
- data/test/stub/railsapp/config/environments/test.rb +0 -22
- data/test/stub/railsapp2/config/environments/test.rb +0 -22
data/benchmark/dispatcher.rb
CHANGED
@@ -2,16 +2,15 @@
|
|
2
2
|
# Benchmark raw speed of the Rails dispatcher.
|
3
3
|
PASSENGER_ROOT = File.expand_path("#{File.dirname(__FILE__)}/..")
|
4
4
|
$LOAD_PATH << "#{PASSENGER_ROOT}/lib"
|
5
|
+
$LOAD_PATH << "#{PASSENGER_ROOT}/ext"
|
5
6
|
ENV["RAILS_ENV"] = "production"
|
6
7
|
|
7
8
|
require 'yaml'
|
8
9
|
require 'benchmark'
|
9
|
-
require 'passenger/request_handler'
|
10
10
|
require 'config/environment'
|
11
|
+
require 'passenger/railz/cgi_fixed'
|
11
12
|
require 'dispatcher'
|
12
13
|
|
13
|
-
include Passenger
|
14
|
-
|
15
14
|
class OutputChannel
|
16
15
|
def write(data)
|
17
16
|
# Black hole
|
@@ -25,7 +24,7 @@ def start(iterations)
|
|
25
24
|
milestone = 1 if milestone == 0
|
26
25
|
result = Benchmark.measure do
|
27
26
|
iterations.times do |i|
|
28
|
-
cgi = CGIFixed.new(headers, output,
|
27
|
+
cgi = PhusionPassenger::Railz::CGIFixed.new(headers, output, output)
|
29
28
|
::Dispatcher.dispatch(cgi,
|
30
29
|
::ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS,
|
31
30
|
cgi.stdoutput)
|
@@ -39,8 +38,5 @@ def start(iterations)
|
|
39
38
|
end
|
40
39
|
|
41
40
|
puts "Benchmark started."
|
42
|
-
|
43
|
-
|
44
|
-
end
|
45
|
-
start(ARGV[0] ? ARGV[0].to_i : 1000)
|
46
|
-
t.join
|
41
|
+
start(ARGV[0] ? ARGV[0].to_i : 2000)
|
42
|
+
|
@@ -27,13 +27,14 @@ $LOAD_PATH.unshift("#{PASSENGER_ROOT}/ext")
|
|
27
27
|
# the start (i.e. not via 'su' or 'sudo').
|
28
28
|
ENV["PATH"] += ":/usr/sbin:/sbin:/usr/local/sbin"
|
29
29
|
|
30
|
-
require '
|
31
|
-
require '
|
32
|
-
require '
|
30
|
+
require 'optparse'
|
31
|
+
require 'phusion_passenger/platform_info'
|
32
|
+
require 'phusion_passenger/dependencies'
|
33
|
+
require 'phusion_passenger/console_text_template'
|
33
34
|
include PlatformInfo
|
34
35
|
|
35
36
|
class Installer
|
36
|
-
include
|
37
|
+
include PhusionPassenger
|
37
38
|
|
38
39
|
PASSENGER_WEBSITE = "http://www.modrails.com/"
|
39
40
|
PHUSION_WEBSITE = "www.phusion.nl"
|
@@ -45,14 +46,25 @@ class Installer
|
|
45
46
|
Dependencies::RubyGems,
|
46
47
|
Dependencies::Rake,
|
47
48
|
Dependencies::Apache2,
|
48
|
-
Dependencies::Apache2_DevHeaders
|
49
|
-
Dependencies::APR_DevHeaders,
|
50
|
-
Dependencies::APU_DevHeaders,
|
51
|
-
Dependencies::FastThread,
|
52
|
-
Dependencies::Rack
|
49
|
+
Dependencies::Apache2_DevHeaders
|
53
50
|
]
|
51
|
+
if Dependencies.fastthread_required?
|
52
|
+
REQUIRED_DEPENDENCIES << Dependencies::FastThread
|
53
|
+
end
|
54
|
+
# Some broken servers don't have apr-config or apu-config installed.
|
55
|
+
# Nevertheless, it is possible to compile Apache modules if Apache
|
56
|
+
# was configured with --included-apr. So here we check whether
|
57
|
+
# apr-config and apu-config are available. If they're not available,
|
58
|
+
# then we only register them as required dependency if no Apache
|
59
|
+
# module can be compiled without their presence.
|
60
|
+
if (PlatformInfo.apr_config && PlatformInfo.apu_config) ||
|
61
|
+
PlatformInfo.apr_config_needed_for_building_apache_modules?
|
62
|
+
REQUIRED_DEPENDENCIES << Dependencies::APR_DevHeaders
|
63
|
+
REQUIRED_DEPENDENCIES << Dependencies::APU_DevHeaders
|
64
|
+
end
|
54
65
|
|
55
|
-
def start
|
66
|
+
def start(automatic = false)
|
67
|
+
@auto = automatic
|
56
68
|
if natively_packaged?
|
57
69
|
check_dependencies || exit(1)
|
58
70
|
show_apache2_config_snippets
|
@@ -147,7 +159,7 @@ private
|
|
147
159
|
# ...
|
148
160
|
# Server compiled with....
|
149
161
|
# -D APACHE_MPM_DIR="server/mpm/prefork"
|
150
|
-
output = `#{
|
162
|
+
output = `#{PlatformInfo.httpd} -V`
|
151
163
|
output =~ /^Server MPM: +(.*)$/
|
152
164
|
if $1
|
153
165
|
mpm = $1.downcase
|
@@ -188,11 +200,11 @@ private
|
|
188
200
|
color_puts '<banner>Compiling and installing Apache 2 module...</banner>'
|
189
201
|
puts "cd #{PASSENGER_ROOT}"
|
190
202
|
if ENV['TRACE']
|
191
|
-
puts "#{RUBY} -S rake --trace clean apache2"
|
192
|
-
return system(RUBY, "-S",
|
203
|
+
puts "#{RUBY} -S #{PlatformInfo.rake} --trace clean apache2"
|
204
|
+
return system(RUBY, "-S", PlatformInfo.rake, "--trace", "clean", "apache2")
|
193
205
|
else
|
194
|
-
puts "#{RUBY} -S rake clean apache2"
|
195
|
-
return system(RUBY, "-S",
|
206
|
+
puts "#{RUBY} -S #{PlatformInfo.rake} clean apache2"
|
207
|
+
return system(RUBY, "-S", PlatformInfo.rake, "clean", "apache2")
|
196
208
|
end
|
197
209
|
end
|
198
210
|
|
@@ -200,7 +212,7 @@ private
|
|
200
212
|
puts
|
201
213
|
line
|
202
214
|
if natively_packaged?
|
203
|
-
module_location = "#{PASSENGER_ROOT}/lib/
|
215
|
+
module_location = "#{PASSENGER_ROOT}/lib/phusion_passenger/mod_passenger.so"
|
204
216
|
else
|
205
217
|
module_location = "#{PASSENGER_ROOT}/ext/apache2/mod_passenger.so"
|
206
218
|
end
|
@@ -251,6 +263,7 @@ private
|
|
251
263
|
end
|
252
264
|
|
253
265
|
def wait(timeout = nil)
|
266
|
+
return if @auto
|
254
267
|
begin
|
255
268
|
if timeout
|
256
269
|
require 'timeout' unless defined?(Timeout)
|
@@ -305,7 +318,7 @@ private
|
|
305
318
|
|
306
319
|
def self.determine_users_guide
|
307
320
|
if natively_packaged?
|
308
|
-
return "/usr/share/doc/
|
321
|
+
return "/usr/share/doc/phusion_passenger/Users guide.html"
|
309
322
|
else
|
310
323
|
return "#{PASSENGER_ROOT}/doc/Users guide.html"
|
311
324
|
end
|
@@ -315,4 +328,25 @@ private
|
|
315
328
|
USERS_GUIDE = determine_users_guide
|
316
329
|
end
|
317
330
|
|
318
|
-
|
331
|
+
options = {}
|
332
|
+
parser = OptionParser.new do |opts|
|
333
|
+
opts.banner = "Usage: passenger-install-apache2-module [options]"
|
334
|
+
opts.separator ""
|
335
|
+
|
336
|
+
opts.separator "Options:"
|
337
|
+
opts.on("-a", "--auto", String, "Automatically build the Apache module,\n" <<
|
338
|
+
"#{' ' * 37}without interactively asking for user\n" <<
|
339
|
+
"#{' ' * 37}input.") do
|
340
|
+
options[:auto] = true
|
341
|
+
end
|
342
|
+
end
|
343
|
+
begin
|
344
|
+
parser.parse!
|
345
|
+
rescue OptionParser::ParseError => e
|
346
|
+
puts e
|
347
|
+
puts
|
348
|
+
puts "Please see '--help' for valid options."
|
349
|
+
exit 1
|
350
|
+
end
|
351
|
+
|
352
|
+
Installer.new.start(options[:auto])
|
data/bin/passenger-memory-stats
CHANGED
@@ -18,7 +18,14 @@
|
|
18
18
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
19
19
|
|
20
20
|
$LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../lib")
|
21
|
-
require '
|
21
|
+
require 'phusion_passenger/platform_info'
|
22
|
+
|
23
|
+
# ANSI color codes
|
24
|
+
RESET = "\e[0m"
|
25
|
+
BOLD = "\e[1m"
|
26
|
+
WHITE = "\e[37m"
|
27
|
+
YELLOW = "\e[33m"
|
28
|
+
BLUE_BG = "\e[44m"
|
22
29
|
|
23
30
|
# Container for tabular data.
|
24
31
|
class Table
|
@@ -64,14 +71,22 @@ class Table
|
|
64
71
|
left_bar_size = free_space / 2
|
65
72
|
right_bar_size = free_space - left_bar_size
|
66
73
|
end
|
67
|
-
result = "#{
|
68
|
-
result <<
|
74
|
+
result = "#{BLUE_BG}#{BOLD}#{YELLOW}"
|
75
|
+
result << "#{"-" * left_bar_size} #{title} #{"-" * right_bar_size}\n"
|
76
|
+
if !@rows.empty?
|
77
|
+
result << WHITE
|
78
|
+
result << header
|
79
|
+
end
|
69
80
|
else
|
70
81
|
result = header.dup
|
71
82
|
end
|
72
|
-
|
73
|
-
|
74
|
-
|
83
|
+
if @rows.empty?
|
84
|
+
result << RESET
|
85
|
+
else
|
86
|
+
result << ("-" * header.size) << "#{RESET}\n"
|
87
|
+
@rows.each do |row|
|
88
|
+
result << sprintf(format_string, *row).rstrip << "\n"
|
89
|
+
end
|
75
90
|
end
|
76
91
|
result
|
77
92
|
end
|
@@ -109,12 +124,25 @@ class MemoryStats
|
|
109
124
|
end
|
110
125
|
|
111
126
|
def start
|
112
|
-
|
127
|
+
if PlatformInfo.httpd.nil?
|
128
|
+
STDERR.puts "*** ERROR: The Apache executable cannot be found."
|
129
|
+
STDERR.puts "Please set the APXS2 environment variable to your 'apxs2' " <<
|
130
|
+
"executable's filename, or set the HTTPD environment variable " <<
|
131
|
+
"to your 'httpd' or 'apache2' executable's filename."
|
132
|
+
exit 1
|
133
|
+
end
|
134
|
+
|
135
|
+
apache_processes = list_processes(:exe => PlatformInfo.httpd)
|
136
|
+
if apache_processes.empty?
|
137
|
+
# On some Linux distros, the Apache worker processes
|
138
|
+
# are called "httpd.worker"
|
139
|
+
apache_processes = list_processes(:exe => "#{PlatformInfo.httpd}.worker")
|
140
|
+
end
|
113
141
|
print_process_list("Apache processes", apache_processes)
|
114
142
|
|
115
143
|
puts
|
116
144
|
passenger_processes = list_processes(:match =>
|
117
|
-
/(
|
145
|
+
/((^| )Passenger |(^| )Rails:|(^| )Rack:|ApplicationPoolServerExecutable)/)
|
118
146
|
print_process_list("Passenger processes", passenger_processes, :show_ppid => false)
|
119
147
|
|
120
148
|
if RUBY_PLATFORM !~ /linux/
|
@@ -141,9 +169,19 @@ class MemoryStats
|
|
141
169
|
def list_processes(options)
|
142
170
|
if options[:exe]
|
143
171
|
name = options[:exe].sub(/.*\/(.*)/, '\1')
|
144
|
-
|
172
|
+
if RUBY_PLATFORM =~ /linux/
|
173
|
+
ps = "ps -C '#{name}'"
|
174
|
+
else
|
175
|
+
ps = "ps -A"
|
176
|
+
options[:match] = Regexp.new(Regexp.escape(name))
|
177
|
+
end
|
145
178
|
elsif options[:name]
|
146
|
-
|
179
|
+
if RUBY_PLATFORM =~ /linux/
|
180
|
+
ps = "ps -C '#{options[:name]}'"
|
181
|
+
else
|
182
|
+
ps = "ps -A"
|
183
|
+
options[:match] = Regexp.new(" #{Regexp.escape(options[:name])}")
|
184
|
+
end
|
147
185
|
elsif options[:match]
|
148
186
|
ps = "ps -A"
|
149
187
|
else
|
@@ -151,21 +189,37 @@ class MemoryStats
|
|
151
189
|
end
|
152
190
|
|
153
191
|
processes = []
|
154
|
-
|
192
|
+
case RUBY_PLATFORM
|
193
|
+
when /solaris/
|
194
|
+
list = `#{ps} -o pid,ppid,nlwp,vsz,rss,comm`.split("\n")
|
195
|
+
threads_known = true
|
196
|
+
when /darwin/
|
197
|
+
list = `#{ps} -w -o pid,ppid,vsz,rss,command`.split("\n")
|
198
|
+
threads_known = false
|
199
|
+
else
|
200
|
+
list = `#{ps} -w -o pid,ppid,nlwp,vsz,rss,command`.split("\n")
|
201
|
+
threads_known = true
|
202
|
+
end
|
155
203
|
list.shift
|
156
204
|
list.each do |line|
|
157
205
|
line.gsub!(/^ */, '')
|
158
206
|
line.gsub!(/ *$/, '')
|
159
207
|
|
160
208
|
p = Process.new
|
161
|
-
|
209
|
+
if threads_known
|
210
|
+
p.pid, p.ppid, p.threads, p.vm_size, p.rss, p.name = line.split(/ +/, 6)
|
211
|
+
else
|
212
|
+
p.pid, p.ppid, p.vm_size, p.rss, p.name = line.split(/ +/, 6)
|
213
|
+
p.threads = "?"
|
214
|
+
end
|
162
215
|
p.name.sub!(/\Aruby: /, '')
|
163
216
|
p.name.sub!(/ \(ruby\)\Z/, '')
|
164
217
|
if p.name !~ /^ps/ && (!options[:match] || p.name.match(options[:match]))
|
165
218
|
# Convert some values to integer.
|
166
|
-
[:pid, :ppid, :
|
219
|
+
[:pid, :ppid, :vm_size, :rss].each do |attr|
|
167
220
|
p.send("#{attr}=", p.send(attr).to_i)
|
168
221
|
end
|
222
|
+
p.threads = p.threads.to_i if threads_known
|
169
223
|
|
170
224
|
if platform_provides_private_dirty_rss_information?
|
171
225
|
p.private_dirty_rss = determine_private_dirty_rss(p.pid)
|
data/bin/passenger-spawn-server
CHANGED
@@ -41,13 +41,17 @@ begin
|
|
41
41
|
exit
|
42
42
|
end
|
43
43
|
|
44
|
-
require '
|
45
|
-
|
44
|
+
require 'phusion_passenger/spawn_manager'
|
45
|
+
require 'phusion_passenger/utils'
|
46
|
+
if defined?(PhusionPassenger::NativeSupport)
|
47
|
+
PhusionPassenger::NativeSupport.disable_stdio_buffering
|
48
|
+
end
|
49
|
+
spawn_manager = PhusionPassenger::SpawnManager.new
|
46
50
|
spawn_manager.start_synchronously(input)
|
47
51
|
spawn_manager.cleanup
|
48
52
|
rescue => e
|
49
|
-
require '
|
50
|
-
include
|
53
|
+
require 'phusion_passenger/utils'
|
54
|
+
include PhusionPassenger::Utils
|
51
55
|
print_exception("spawn manager", e)
|
52
56
|
exit 10
|
53
57
|
end
|
data/bin/passenger-status
CHANGED
@@ -19,63 +19,38 @@
|
|
19
19
|
|
20
20
|
$LOAD_PATH << File.expand_path(File.dirname(__FILE__) + "/../lib")
|
21
21
|
$LOAD_PATH << File.expand_path(File.dirname(__FILE__) + "/../ext")
|
22
|
+
require 'phusion_passenger/admin_tools/control_process'
|
22
23
|
|
23
|
-
|
24
|
-
attr_accessor :filename
|
25
|
-
attr_accessor :pid
|
26
|
-
|
27
|
-
def initialize(filename, pid)
|
28
|
-
@filename = filename
|
29
|
-
@pid = pid
|
30
|
-
end
|
31
|
-
end
|
24
|
+
include PhusionPassenger::AdminTools
|
32
25
|
|
33
|
-
#
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
filename =~ /(\d+).fifo$/
|
39
|
-
pid = $1.to_i
|
40
|
-
if process_is_alive?(pid)
|
41
|
-
result << StatusFifo.new(filename, pid)
|
42
|
-
else
|
43
|
-
puts "*** NOTICE: Removing stale status FIFO file #{filename}"
|
44
|
-
File.unlink(filename) rescue nil
|
45
|
-
end
|
46
|
-
end
|
47
|
-
return result
|
48
|
-
end
|
26
|
+
# ANSI color codes
|
27
|
+
RESET = "\e[0m"
|
28
|
+
BOLD = "\e[1m"
|
29
|
+
YELLOW = "\e[33m"
|
30
|
+
BLUE_BG = "\e[44m"
|
49
31
|
|
50
|
-
def
|
32
|
+
def show_status(control_process, format = :text)
|
51
33
|
begin
|
52
|
-
|
53
|
-
return true
|
54
|
-
rescue Errno::ESRCH
|
55
|
-
return false
|
34
|
+
text = control_process.status
|
56
35
|
rescue SystemCallError => e
|
57
|
-
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def show_status(status_fifo)
|
62
|
-
begin
|
63
|
-
puts File.read(status_fifo.filename)
|
64
|
-
rescue => e
|
65
|
-
STDERR.puts "*** ERROR: Cannot query status for Passenger instance #{status_fifo.pid}:"
|
36
|
+
STDERR.puts "*** ERROR: Cannot query status for Passenger instance #{control_process.pid}:"
|
66
37
|
STDERR.puts e.to_s
|
67
38
|
exit 2
|
68
39
|
end
|
40
|
+
# Colorize output
|
41
|
+
text.gsub!(/^(----)(.*)$/, YELLOW + BLUE_BG + BOLD + '\1\2' + RESET)
|
42
|
+
text.gsub!(/^( +in '.*? )(.*?)\(/, '\1' + BOLD + '\2' + RESET + '(')
|
43
|
+
puts text
|
69
44
|
end
|
70
45
|
|
71
46
|
def start
|
72
47
|
if ARGV.empty?
|
73
|
-
|
74
|
-
if
|
48
|
+
control_processes = ControlProcess.list
|
49
|
+
if control_processes.empty?
|
75
50
|
STDERR.puts("ERROR: Phusion Passenger doesn't seem to be running.")
|
76
51
|
exit 2
|
77
|
-
elsif
|
78
|
-
show_status(
|
52
|
+
elsif control_processes.size == 1
|
53
|
+
show_status(control_processes.first)
|
79
54
|
else
|
80
55
|
puts "It appears that multiple Passenger instances are running. Please select a"
|
81
56
|
puts "specific one by running:"
|
@@ -83,13 +58,13 @@ def start
|
|
83
58
|
puts " passenger-status <PID>"
|
84
59
|
puts
|
85
60
|
puts "The following Passenger instances are running:"
|
86
|
-
|
87
|
-
puts " PID: #{
|
61
|
+
control_processes.each do |control|
|
62
|
+
puts " PID: #{control.pid}"
|
88
63
|
end
|
89
64
|
exit 1
|
90
65
|
end
|
91
66
|
else
|
92
|
-
show_status(
|
67
|
+
show_status(ControlProcess.new(ARGV[0].to_i))
|
93
68
|
end
|
94
69
|
end
|
95
70
|
|
data/bin/passenger-stress-test
CHANGED
@@ -23,12 +23,12 @@ require 'rubygems'
|
|
23
23
|
require 'optparse'
|
24
24
|
require 'socket'
|
25
25
|
require 'thread'
|
26
|
-
require '
|
27
|
-
require '
|
28
|
-
require '
|
26
|
+
require 'phusion_passenger/platform_info'
|
27
|
+
require 'phusion_passenger/message_channel'
|
28
|
+
require 'phusion_passenger/utils'
|
29
29
|
|
30
|
-
include
|
31
|
-
include
|
30
|
+
include PhusionPassenger
|
31
|
+
include PhusionPassenger::Utils
|
32
32
|
include PlatformInfo
|
33
33
|
|
34
34
|
# A thread or a process, depending on the Ruby VM implementation.
|
data/debian/postinst
CHANGED
@@ -3,17 +3,27 @@
|
|
3
3
|
|
4
4
|
== Introduction
|
5
5
|
|
6
|
-
For efficiency reasons, Passenger keeps a pool spawned Rails applications.
|
6
|
+
For efficiency reasons, Passenger keeps a pool spawned Rails/Ruby applications.
|
7
7
|
Please read the C++ API documentation for the ApplicationPool class for a full
|
8
|
-
introduction. This document describes an algorithm for managing the pool
|
8
|
+
introduction. This document describes an algorithm for managing the pool, in a
|
9
|
+
high-level way.
|
9
10
|
|
10
11
|
The algorithm should strive to keep spawning to a minimum.
|
11
12
|
|
12
|
-
TODO: check whether the algorithm has thrashing behavior.
|
13
|
-
|
14
13
|
|
15
14
|
== Definitions
|
16
15
|
|
16
|
+
=== Vocabulary
|
17
|
+
|
18
|
+
- "Application root":
|
19
|
+
The toplevel directory in which an application is contained. For Rails
|
20
|
+
application, this is the same as RAILS_ROOT, i.e. the directory that contains
|
21
|
+
"app/", "public/", etc. For a Rack application, this is the directory that
|
22
|
+
contains "config.ru".
|
23
|
+
|
24
|
+
- "Active application instance":
|
25
|
+
An application instance that has more than 0 active sessions.
|
26
|
+
|
17
27
|
=== Types
|
18
28
|
|
19
29
|
Most of the types that we use in this document are pretty standard. But we
|
@@ -35,13 +45,44 @@ explicitly define some special types:
|
|
35
45
|
Moves the specified element to the front of the list. _iterator_ is an
|
36
46
|
iterator, as described earlier.
|
37
47
|
|
48
|
+
- Domain
|
49
|
+
A compound type (class) which contains information about an application root,
|
50
|
+
such as the application instances that have been spawned for this application
|
51
|
+
root.
|
52
|
+
|
53
|
+
A Domain has the following members:
|
54
|
+
* instances (list<AppContainer>) - a list of AppContainer objects.
|
55
|
+
|
56
|
+
Invariant:
|
57
|
+
containers is non-empty.
|
58
|
+
for all 0 <= i < containers.size() - 1:
|
59
|
+
if containers[i].app is active:
|
60
|
+
containers[i + 1].app is active
|
61
|
+
|
62
|
+
* size (unsigned integer): The number of items in _instances_.
|
63
|
+
|
64
|
+
* max_requests (unsigned integer): The maximum number of requests that each
|
65
|
+
application instance in this domain may process. After having processed this
|
66
|
+
many requests, the application instance will be shut down.
|
67
|
+
A value of 0 indicates that there is no maximum.
|
68
|
+
|
69
|
+
* restart_file_checker
|
70
|
+
An object which monitors the restart.txt file, which belongs to this
|
71
|
+
application root, for changes. This object has the method changed(),
|
72
|
+
which rteurns whether restart.txt's timestamp has changed since the last
|
73
|
+
check.
|
74
|
+
|
38
75
|
- AppContainer
|
39
|
-
A compound type which contains an application instance, as well as
|
40
|
-
for various linked lists. These iterators make it possible to
|
41
|
-
on the linked list in O(1) time.
|
76
|
+
A compound type (class) which contains an application instance, as well as
|
77
|
+
iterators for various linked lists. These iterators make it possible to
|
78
|
+
perform actions on the linked list in O(1) time.
|
42
79
|
|
43
80
|
An AppContainer has the following members:
|
44
81
|
* app - An Application object, representing an application instance.
|
82
|
+
* start_time (time) - The time at which this application instance was
|
83
|
+
started. It's set to the current time by AppContainer's constructor.
|
84
|
+
* processed_requests (integer) - The number of requests processed by this
|
85
|
+
application instance so far.
|
45
86
|
* last_used (time) - The last time a session for this application instance
|
46
87
|
was opened or closed.
|
47
88
|
* sessions (integer) - The number of open sessions for this application
|
@@ -49,11 +90,24 @@ explicitly define some special types:
|
|
49
90
|
Invariant:
|
50
91
|
(sessions == 0) == (This AppContainer is in inactive_apps.)
|
51
92
|
* iterator - The iterator for this AppContainer in the linked list
|
52
|
-
|
93
|
+
domains[app.app_root].instances
|
53
94
|
* ia_iterator - The iterator for this AppContainer in the linked list
|
54
95
|
inactive_apps. This iterator is only valid if this AppContainer really is
|
55
96
|
in that list.
|
56
97
|
|
98
|
+
- PoolOptions
|
99
|
+
A structure containing additional information used by the spawn manager's
|
100
|
+
spawning process, as well as by the get() function.
|
101
|
+
|
102
|
+
A PoolOptions has the following members:
|
103
|
+
* max_requests (unsigned integer) - The maximum number of requests that the
|
104
|
+
application instance may process. After having processed this many requests,
|
105
|
+
the application instance will be shut down. A value of 0 indicates that there
|
106
|
+
is no maximum.
|
107
|
+
* use_global_queue (boolean) - Whether to use a global queue for all
|
108
|
+
application instances, or a queue that's private to the application instance.
|
109
|
+
The users guide explains this feature in more detail.
|
110
|
+
|
57
111
|
=== Special functions
|
58
112
|
|
59
113
|
- spawn(app_root)
|
@@ -71,33 +125,29 @@ information:
|
|
71
125
|
is non-recursive, i.e. if a thread locks a mutex that it has already locked,
|
72
126
|
then it will result in a deadlock.
|
73
127
|
|
74
|
-
-
|
75
|
-
Maps an application root to
|
76
|
-
|
128
|
+
- domains: map[string => Domain]
|
129
|
+
Maps an application root to its Domain object. This map contains all
|
130
|
+
application instances in the pool.
|
77
131
|
|
78
132
|
Invariant:
|
79
|
-
for all values
|
80
|
-
|
81
|
-
|
82
|
-
if v[i].app is active:
|
83
|
-
v[i + 1].app is active
|
133
|
+
for all values d in domains:
|
134
|
+
d.size <= count
|
135
|
+
(sum of all d.size in domains) == count
|
84
136
|
|
85
|
-
An active application is one that has more than 0 active sessions.
|
86
|
-
|
87
137
|
- max: integer
|
88
|
-
The maximum number of AppContainer objects that may exist in
|
138
|
+
The maximum number of AppContainer objects that may exist in the pool.
|
89
139
|
|
90
140
|
- max_per_app: integer
|
91
|
-
The maximum number of
|
92
|
-
|
141
|
+
The maximum number of AppContainer objects that may be simultaneously alive
|
142
|
+
for a single Domain.
|
93
143
|
|
94
144
|
- count: integer
|
95
|
-
The current number of AppContainer objects in
|
145
|
+
The current number of AppContainer objects in the pool.
|
96
146
|
Since 'max' can be set dynamically during the life time of an application
|
97
147
|
pool, 'count > max' is possible.
|
98
148
|
|
99
149
|
- active: integer
|
100
|
-
The number of application instances in
|
150
|
+
The number of application instances in the pool that are active.
|
101
151
|
Invariant:
|
102
152
|
active <= count
|
103
153
|
|
@@ -108,31 +158,29 @@ information:
|
|
108
158
|
Invariant:
|
109
159
|
inactive_apps.size() == count - active
|
110
160
|
for all c in inactive_apps:
|
111
|
-
c
|
161
|
+
c can be found in _domains_.
|
112
162
|
c.sessions == 0
|
113
163
|
|
114
|
-
- restart_file_times: map[string => time]
|
115
|
-
Maps an application root to the last known modification time of
|
116
|
-
'restart.txt'.
|
117
|
-
|
118
|
-
Invariant:
|
119
|
-
for all keys app_root in restart_times:
|
120
|
-
apps.has_key(app_root)
|
121
|
-
|
122
164
|
- waiting_on_global_queue: integer
|
123
165
|
If global queuing mode is enabled, then when get() is waiting for a backend
|
124
166
|
process to become idle, this variable will be incremented. When get() is done
|
125
167
|
waiting, this variable will be decremented.
|
126
168
|
|
127
|
-
- app_instance_count: map[string => unsigned int]
|
128
|
-
Maps an application root to the number of spawned applications.
|
129
169
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
170
|
+
== Class relations
|
171
|
+
|
172
|
+
Here's an UML diagram in ASCII art:
|
173
|
+
|
174
|
+
[AppContainer] 1..* -------+
|
175
|
+
|
|
176
|
+
|
|
177
|
+
|
178
|
+
1
|
179
|
+
[ApplicationPool] [Domain]
|
180
|
+
1 0..*
|
181
|
+
|
182
|
+
| |
|
183
|
+
+-------------------+
|
136
184
|
|
137
185
|
|
138
186
|
== Algorithm in pseudo code
|
@@ -140,64 +188,68 @@ information:
|
|
140
188
|
# Thread-safetiness notes:
|
141
189
|
# - All wait commands are to unlock the lock during waiting.
|
142
190
|
|
143
|
-
|
191
|
+
# Connect to an existing application instance or to a newly spawned application instance.
|
192
|
+
# 'app_root' specifies the application root folder of the application. 'options' is an
|
193
|
+
# object of type 'PoolOptions', which contains additional information which may be
|
194
|
+
# relevant for spawning.
|
195
|
+
function get(app_root, options):
|
144
196
|
MAX_ATTEMPTS = 10
|
145
197
|
attempt = 0
|
146
198
|
time_limit = now() + 5 seconds
|
147
199
|
lock.synchronize:
|
148
200
|
while (true):
|
149
201
|
attempt++
|
150
|
-
container,
|
202
|
+
container, domain = spawn_or_use_existing(app_root, options)
|
151
203
|
container.last_used = current_time()
|
152
204
|
container.sessions++
|
153
205
|
try:
|
154
206
|
return container.app.connect()
|
155
207
|
on exception:
|
208
|
+
# The app instance seems to have crashed.
|
209
|
+
# So we remove this instance from our data
|
210
|
+
# structures.
|
156
211
|
container.sessions--
|
212
|
+
instances = domain.instances
|
213
|
+
instances.remove(container.iterator)
|
214
|
+
domain.size--
|
215
|
+
if instances.empty():
|
216
|
+
domains.remove(app_root)
|
217
|
+
count--
|
218
|
+
active--
|
157
219
|
if (attempt == MAX_ATTEMPTS):
|
158
220
|
propagate exception
|
159
|
-
else:
|
160
|
-
# The app instance seems to have crashed.
|
161
|
-
# So we remove this instance from our data
|
162
|
-
# structures.
|
163
|
-
list.remove(container.iterator)
|
164
|
-
if list.empty():
|
165
|
-
apps.remove(app_root)
|
166
|
-
app_instance_count.remove(app_root)
|
167
|
-
count--
|
168
|
-
active--
|
169
221
|
|
170
222
|
|
171
|
-
# Returns a pair of [AppContainer,
|
172
|
-
#
|
173
|
-
#
|
174
|
-
|
175
|
-
|
176
|
-
list = apps[app_root]
|
223
|
+
# Returns a pair of [AppContainer, Domain] that matches the given application
|
224
|
+
# root. If no such AppContainer exists, then it is created and a new
|
225
|
+
# application instance is spawned. All exceptions that occur are propagated.
|
226
|
+
function spawn_or_use_existing(app_root, options):
|
227
|
+
domain = domains[app_root]
|
177
228
|
|
178
|
-
if (
|
179
|
-
for all container in
|
229
|
+
if (domain != nil) and (needs_restart(app_root, domain)):
|
230
|
+
for all container in domain.instances:
|
180
231
|
if container.sessions == 0:
|
181
232
|
inactive_apps.remove(container.ia_iterator)
|
182
233
|
else:
|
183
234
|
active--
|
184
|
-
|
235
|
+
domain.instances.remove(container.iterator)
|
185
236
|
count--
|
186
|
-
|
187
|
-
app_instance_count.remove(app_root)
|
237
|
+
domains.remove(app_root)
|
188
238
|
list = nil
|
189
239
|
Tell spawn server to reload code for app_root.
|
190
240
|
|
191
|
-
if
|
241
|
+
if domain != nil:
|
192
242
|
# There are apps for this app root.
|
193
|
-
|
243
|
+
instances = domain.instances
|
244
|
+
|
245
|
+
if (instances.front.sessions == 0):
|
194
246
|
# There is an inactive app, so we use it.
|
195
|
-
container =
|
196
|
-
|
247
|
+
container = instances.front
|
248
|
+
instances.move_to_back(container.iterator)
|
197
249
|
inactive_apps.remove(container.ia_iterator)
|
198
250
|
active++
|
199
251
|
else if (count >= max) or (
|
200
|
-
(max_per_app != 0) and (
|
252
|
+
(max_per_app != 0) and (domain.size >= max_per_app)
|
201
253
|
):
|
202
254
|
# All apps are active, and the pool is full.
|
203
255
|
# -OR-
|
@@ -205,7 +257,7 @@ function spawn_or_use_existing(app_root):
|
|
205
257
|
# spawned for this application domain has been reached.
|
206
258
|
#
|
207
259
|
# We're not allowed to spawn a new application instance.
|
208
|
-
if use_global_queue:
|
260
|
+
if options.use_global_queue:
|
209
261
|
# So we wait until _active_ has changed, then
|
210
262
|
# we restart this function and try again.
|
211
263
|
waiting_on_global_queue++
|
@@ -216,8 +268,8 @@ function spawn_or_use_existing(app_root):
|
|
216
268
|
# So we connect to an already active application.
|
217
269
|
# This connection will be put into that
|
218
270
|
# application's private queue.
|
219
|
-
container = a container in
|
220
|
-
|
271
|
+
container = a container in _instances_ with the smallest _session_ value
|
272
|
+
instances.move_to_back(container.iterator)
|
221
273
|
else:
|
222
274
|
# All apps are active, but the pool hasn't reached its
|
223
275
|
# maximum yet. So we spawn a new app.
|
@@ -225,9 +277,9 @@ function spawn_or_use_existing(app_root):
|
|
225
277
|
# TODO: we should add some kind of timeout check for spawning.
|
226
278
|
container.app = spawn(app_root)
|
227
279
|
container.sessions = 0
|
228
|
-
iterator =
|
280
|
+
iterator = instances.add_to_back(container)
|
229
281
|
container.iterator = iterator
|
230
|
-
|
282
|
+
domain.size++
|
231
283
|
count++
|
232
284
|
active++
|
233
285
|
else:
|
@@ -239,11 +291,7 @@ function spawn_or_use_existing(app_root):
|
|
239
291
|
if (active >= max):
|
240
292
|
wait until _active_ has changed
|
241
293
|
goto beginning of function
|
242
|
-
|
243
|
-
# waiting and having reacquired the lock, the state might have
|
244
|
-
# been completely changed, and there may now exist an instance
|
245
|
-
# of this application domain.
|
246
|
-
if count == max:
|
294
|
+
elsif count == max:
|
247
295
|
# Here we are in a though situation. There are several
|
248
296
|
# apps which are inactive, and none of them have
|
249
297
|
# application root _app_root_, so we must kill one of
|
@@ -256,31 +304,33 @@ function spawn_or_use_existing(app_root):
|
|
256
304
|
# killed. But for now, we kill a random application
|
257
305
|
# instance.
|
258
306
|
container = inactive_apps.pop_front
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
app_instance_count.remove(container.app.app_root)
|
307
|
+
domain = domains[container.app.app_root]
|
308
|
+
instances = domain.instances
|
309
|
+
instances.remove(container.iterator)
|
310
|
+
if instances.empty():
|
311
|
+
domains.remove(container.app.app_root)
|
265
312
|
else:
|
266
|
-
|
313
|
+
domain.size--
|
267
314
|
count--
|
268
315
|
container = new AppContainer
|
269
316
|
# TODO: we should add some kind of timeout check for spawning.
|
270
317
|
container.app = spawn(app_root)
|
271
318
|
container.sessions = 0
|
272
|
-
|
273
|
-
if
|
274
|
-
|
275
|
-
|
276
|
-
|
319
|
+
domain = domains[app_root]
|
320
|
+
if domain == nil:
|
321
|
+
domain = new Domain
|
322
|
+
initialize domain.instances
|
323
|
+
initialize domain.restart_file_checker with "$app_root/tmp/restart.txt"
|
324
|
+
domain.size = 1
|
325
|
+
domain.max_requests = options.max_requests
|
326
|
+
domains[app_root] = domain
|
277
327
|
else:
|
278
|
-
|
279
|
-
iterator =
|
328
|
+
domain.size++
|
329
|
+
iterator = domain.instances.add_to_back(container)
|
280
330
|
container.iterator = iterator
|
281
331
|
count++
|
282
332
|
active++
|
283
|
-
return [container,
|
333
|
+
return [container, domain]
|
284
334
|
|
285
335
|
|
286
336
|
# The following function is to be called when a session has been closed.
|
@@ -288,39 +338,39 @@ function spawn_or_use_existing(app_root):
|
|
288
338
|
# session has been closed.
|
289
339
|
function session_has_been_closed(container):
|
290
340
|
lock.synchronize:
|
291
|
-
|
292
|
-
if
|
293
|
-
|
294
|
-
container.
|
295
|
-
|
296
|
-
|
297
|
-
|
341
|
+
domain = domains[container.app.app_root]
|
342
|
+
if domain != nil:
|
343
|
+
instances = domain.instances
|
344
|
+
container.processed++
|
345
|
+
|
346
|
+
if (domain.max_requests) > 0 and (container.processed >= domain.max_requests):
|
347
|
+
# The application instance has processed its maximum allowed
|
348
|
+
# number of requests, so we shut it down.
|
349
|
+
instances.remove(container.iterator)
|
350
|
+
domain.size--
|
351
|
+
if instances.empty():
|
352
|
+
domains.remove(app_root)
|
353
|
+
count--
|
298
354
|
active--
|
355
|
+
else:
|
356
|
+
container.last_used = current_time()
|
357
|
+
container.sessions--
|
358
|
+
container.processed++
|
359
|
+
if container.sessions == 0:
|
360
|
+
instances.move_to_front(container.iterator)
|
361
|
+
container.ia_iterator = inactive_apps.add_to_back(container.app)
|
362
|
+
active--
|
299
363
|
|
300
364
|
|
301
|
-
function needs_restart(app_root):
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
delete_file(restart_file)
|
306
|
-
if (deletion was successful) or (file was already deleted):
|
307
|
-
restart_file_times.remove(app_root)
|
308
|
-
result = true
|
309
|
-
else:
|
310
|
-
last_restart_file_time = restart_file_times[app_root]
|
311
|
-
if last_restart_time == null:
|
312
|
-
result = true
|
313
|
-
else:
|
314
|
-
result = s.mtime != last_restart_file_time
|
315
|
-
restart_file_times[app_root] = s.mtime
|
316
|
-
else:
|
317
|
-
restart_file_times.remove(app_root)
|
318
|
-
result = false
|
319
|
-
return result
|
365
|
+
function needs_restart(app_root, domain):
|
366
|
+
always_restart_file = "$app_root/tmp/always_restart.txt"
|
367
|
+
return (file_exists(always_restart_file)) or
|
368
|
+
(domain.restart_file_checker.changed())
|
320
369
|
|
321
370
|
|
322
371
|
# The following thread will be responsible for cleaning up idle application
|
323
372
|
# instances, i.e. instances that haven't been used for a while.
|
373
|
+
# This can be disabled per app when setting it's maxIdleTime to 0.
|
324
374
|
thread cleaner:
|
325
375
|
lock.synchronize:
|
326
376
|
done = false
|
@@ -333,14 +383,16 @@ thread cleaner:
|
|
333
383
|
now = current_time()
|
334
384
|
for all container in inactive_apps:
|
335
385
|
app = container.app
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
386
|
+
domain = domains[app.app_root]
|
387
|
+
instances = domain.instances
|
388
|
+
# If MAX_IDLE_TIME is 0 we don't clean up the instance,
|
389
|
+
# giving us the option to persist the app container
|
390
|
+
# forever unless it's killed by another app.
|
391
|
+
if (MAX_IDLE_TIME > 0) and (now - container.last_used > MAX_IDLE_TIME):
|
392
|
+
instances.remove(container.iterator)
|
393
|
+
inactive_apps.remove(container.iterator)
|
394
|
+
domain.size--
|
341
395
|
count--
|
342
|
-
if
|
343
|
-
|
344
|
-
app_instance_count.remove(app.app_root)
|
345
|
-
restart_file_times.remove(app.app_root)
|
396
|
+
if instances.empty():
|
397
|
+
domains.remove(app.app_root)
|
346
398
|
|