passenger 4.0.30 → 4.0.31
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.tar.gz.asc +7 -7
- data/NEWS +31 -0
- data/bin/passenger +5 -5
- data/bin/passenger-config +6 -126
- data/bin/passenger-install-apache2-module +108 -26
- data/bin/passenger-install-nginx-module +81 -27
- data/bin/passenger-memory-stats +7 -6
- data/bin/passenger-status +13 -10
- data/build/agents.rb +8 -12
- data/build/apache2.rb +12 -7
- data/build/basics.rb +28 -20
- data/build/common_library.rb +4 -4
- data/build/cplusplus_support.rb +4 -4
- data/build/cxx_tests.rb +5 -3
- data/build/debian.rb +1 -2
- data/build/integration_tests.rb +25 -9
- data/build/misc.rb +2 -2
- data/build/oxt_tests.rb +5 -6
- data/build/packaging.rb +72 -40
- data/build/ruby_tests.rb +5 -1
- data/build/test_basics.rb +1 -2
- data/debian.template/locations.ini.template +1 -0
- data/debian.template/rules.template +2 -1
- data/dev/install_scripts_bootstrap_code.rb +42 -0
- data/dev/run_travis.sh +1 -0
- data/dev/runner +27 -0
- data/doc/Packaging.txt.md +5 -10
- data/doc/Users guide Apache.idmap.txt +3 -1
- data/doc/Users guide Apache.txt +5 -3
- data/doc/Users guide Nginx.idmap.txt +9 -5
- data/doc/Users guide Nginx.txt +47 -17
- data/doc/users_guide_snippets/environment_variables.txt +2 -2
- data/doc/users_guide_snippets/installation.txt +6 -2
- data/doc/users_guide_snippets/tips.txt +4 -0
- data/ext/apache2/Hooks.cpp +16 -3
- data/ext/common/Account.h +6 -5
- data/ext/common/AgentsStarter.h +1 -1
- data/ext/common/ApplicationPool2/Common.h +72 -0
- data/ext/common/ApplicationPool2/Group.h +263 -148
- data/ext/common/ApplicationPool2/Implementation.cpp +66 -44
- data/ext/common/ApplicationPool2/Options.h +1 -7
- data/ext/common/ApplicationPool2/Pool.h +96 -72
- data/ext/common/ApplicationPool2/Process.h +12 -17
- data/ext/common/ApplicationPool2/Socket.h +4 -4
- data/ext/common/ApplicationPool2/SuperGroup.h +20 -17
- data/ext/common/Constants.h +15 -1
- data/ext/common/MessageServer.h +22 -0
- data/ext/common/Utils.cpp +4 -1
- data/ext/common/Utils.h +3 -1
- data/ext/common/Utils/StrIntUtils.h +1 -0
- data/ext/common/Utils/Timer.h +15 -1
- data/ext/common/Utils/utf8/checked.h +0 -0
- data/ext/common/Utils/utf8/core.h +0 -0
- data/ext/common/Utils/utf8/unchecked.h +0 -0
- data/ext/common/agents/Base.cpp +59 -35
- data/ext/common/agents/HelperAgent/Main.cpp +23 -12
- data/ext/common/agents/HelperAgent/RequestHandler.h +10 -1
- data/ext/common/agents/LoggingAgent/FilterSupport.h +9 -5
- data/ext/common/agents/TempDirToucher.c +12 -3
- data/ext/common/agents/Watchdog/Main.cpp +8 -2
- data/ext/nginx/ConfigurationCommands.c +10 -0
- data/ext/nginx/ConfigurationFields.h +2 -0
- data/ext/nginx/ContentHandler.c +32 -19
- data/ext/nginx/CreateLocationConfig.c +5 -0
- data/ext/nginx/MergeLocationConfig.c +6 -0
- data/ext/nginx/config +13 -6
- data/ext/ruby/passenger_native_support.c +61 -2
- data/helper-scripts/classic-rails-loader.rb +9 -10
- data/helper-scripts/classic-rails-preloader.rb +10 -11
- data/helper-scripts/node-loader.js +3 -2
- data/helper-scripts/rack-loader.rb +8 -9
- data/helper-scripts/rack-preloader.rb +9 -10
- data/lib/phusion_passenger.rb +36 -7
- data/lib/phusion_passenger/abstract_installer.rb +16 -15
- data/lib/phusion_passenger/active_support3_extensions/init.rb +1 -1
- data/lib/phusion_passenger/admin_tools/memory_stats.rb +2 -2
- data/lib/phusion_passenger/admin_tools/server_instance.rb +5 -5
- data/lib/phusion_passenger/analytics_logger.rb +3 -3
- data/lib/phusion_passenger/classic_rails/thread_handler_extension.rb +1 -1
- data/lib/phusion_passenger/config.rb +125 -0
- data/lib/phusion_passenger/config/about_command.rb +183 -0
- data/lib/phusion_passenger/config/command.rb +57 -0
- data/lib/phusion_passenger/config/restart_app_command.rb +146 -0
- data/lib/phusion_passenger/config/utils.rb +108 -0
- data/lib/phusion_passenger/console_text_template.rb +2 -1
- data/lib/phusion_passenger/constants.rb +7 -2
- data/lib/phusion_passenger/loader_shared_helpers.rb +12 -21
- data/lib/phusion_passenger/message_client.rb +15 -4
- data/lib/phusion_passenger/native_support.rb +116 -98
- data/lib/phusion_passenger/nginx/config_options.rb +5 -0
- data/lib/phusion_passenger/platform_info.rb +1 -1
- data/lib/phusion_passenger/platform_info/apache.rb +9 -5
- data/lib/phusion_passenger/platform_info/apache_detector.rb +5 -6
- data/lib/phusion_passenger/platform_info/binary_compatibility.rb +3 -3
- data/lib/phusion_passenger/platform_info/compiler.rb +29 -11
- data/lib/phusion_passenger/platform_info/curl.rb +1 -1
- data/lib/phusion_passenger/platform_info/cxx_portability.rb +30 -16
- data/lib/phusion_passenger/platform_info/depcheck.rb +6 -6
- data/lib/phusion_passenger/platform_info/linux.rb +2 -2
- data/lib/phusion_passenger/platform_info/operating_system.rb +25 -5
- data/lib/phusion_passenger/platform_info/ruby.rb +7 -4
- data/lib/phusion_passenger/platform_info/zlib.rb +1 -1
- data/lib/phusion_passenger/plugin.rb +0 -1
- data/lib/phusion_passenger/preloader_shared_helpers.rb +1 -1
- data/lib/phusion_passenger/public_api.rb +1 -1
- data/lib/phusion_passenger/rack/thread_handler_extension.rb +1 -1
- data/lib/phusion_passenger/request_handler.rb +8 -9
- data/lib/phusion_passenger/request_handler/thread_handler.rb +21 -9
- data/lib/phusion_passenger/ruby_core_enhancements.rb +1 -1
- data/lib/phusion_passenger/standalone/app_finder.rb +2 -2
- data/lib/phusion_passenger/standalone/command.rb +10 -8
- data/lib/phusion_passenger/standalone/help_command.rb +1 -1
- data/lib/phusion_passenger/standalone/main.rb +3 -3
- data/lib/phusion_passenger/standalone/package_runtime_command.rb +2 -2
- data/lib/phusion_passenger/standalone/runtime_installer.rb +55 -13
- data/lib/phusion_passenger/standalone/runtime_locator.rb +3 -3
- data/lib/phusion_passenger/standalone/start_command.rb +6 -7
- data/lib/phusion_passenger/standalone/status_command.rb +1 -1
- data/lib/phusion_passenger/standalone/stop_command.rb +1 -1
- data/lib/phusion_passenger/standalone/utils.rb +1 -1
- data/lib/phusion_passenger/standalone/version_command.rb +2 -3
- data/lib/phusion_passenger/utils.rb +1 -1
- data/lib/phusion_passenger/utils/download.rb +1 -2
- data/lib/phusion_passenger/utils/file_system_watcher.rb +1 -1
- data/lib/phusion_passenger/utils/hosts_file_parser.rb +1 -1
- data/lib/phusion_passenger/utils/tee_input.rb +1 -1
- data/lib/phusion_passenger/utils/terminal_choice_menu.rb +217 -0
- data/lib/phusion_passenger/utils/unseekable_socket.rb +1 -1
- data/resources/templates/apache2/config_snippets.txt.erb +2 -3
- data/resources/templates/apache2/deployment_example.txt.erb +2 -2
- data/resources/templates/apache2/notify_apache_module_installed.txt.erb +3 -0
- data/resources/templates/nginx/config_snippets.txt.erb +1 -1
- data/resources/templates/nginx/deployment_example.txt.erb +2 -2
- data/resources/templates/nginx/nginx_module_sources_not_available.txt.erb +11 -5
- data/rpm/Vagrantfile +1 -0
- data/test/cxx/ApplicationPool2/PoolTest.cpp +224 -35
- data/test/cxx/ApplicationPool2/ProcessTest.cpp +6 -6
- data/test/cxx/MessagePassingTest.cpp +1 -1
- data/test/cxx/RequestHandlerTest.cpp +26 -26
- data/test/integration_tests/apache2_tests.rb +162 -243
- data/test/integration_tests/native_packaging_spec.rb +10 -10
- data/test/integration_tests/nginx_tests.rb +87 -107
- data/test/integration_tests/shared/example_webapp_tests.rb +246 -0
- data/test/integration_tests/source_packaging_test.rb +2 -1
- data/test/integration_tests/standalone_tests.rb +34 -19
- data/test/ruby/admin_tools_spec.rb +4 -4
- data/test/ruby/analytics_logger_spec.rb +1 -1
- data/test/ruby/debug_logging_spec.rb +2 -2
- data/test/ruby/message_channel_spec.rb +1 -1
- data/test/ruby/request_handler_spec.rb +171 -64
- data/test/ruby/shared/loader_sharedspec.rb +5 -5
- data/test/ruby/shared/rails/analytics_logging_extensions_sharedspec.rb +2 -2
- data/test/ruby/spec_helper.rb +4 -4
- data/test/ruby/standalone/runtime_installer_spec.rb +1 -1
- data/test/ruby/standalone/runtime_locator_spec.rb +1 -1
- data/test/ruby/utils/file_system_watcher_spec.rb +1 -1
- data/test/ruby/utils/hosts_file_parser.rb +1 -1
- data/test/ruby/utils/unseekable_socket_spec.rb +1 -1
- data/test/ruby/utils_spec.rb +4 -4
- data/test/stub/apache2/httpd.conf.erb +5 -0
- data/test/stub/index.html +1 -0
- data/test/stub/rack/config.ru +80 -33
- data/test/stub/{rails_apps/1.2/empty/app/models → rack/public}/.gitignore +0 -0
- data/test/stub/{rails_apps/1.2/empty → rails2.3-mycook}/Rakefile +0 -0
- data/test/stub/{rails_apps/2.3/mycook → rails2.3-mycook}/app/controllers/application_controller.rb +0 -0
- data/test/stub/{rails_apps/2.3/mycook → rails2.3-mycook}/app/controllers/recipes_controller.rb +0 -0
- data/test/stub/{rails_apps/2.3/mycook → rails2.3-mycook}/app/controllers/uploads_controller.rb +0 -0
- data/test/stub/{rails_apps/2.3/mycook → rails2.3-mycook}/app/controllers/welcome_controller.rb +0 -0
- data/test/stub/{rails_apps/1.2/empty → rails2.3-mycook}/app/helpers/application_helper.rb +0 -0
- data/test/stub/{rails_apps/2.3/mycook → rails2.3-mycook}/app/helpers/recipes_helper.rb +0 -0
- data/test/stub/{rails_apps/2.3/mycook → rails2.3-mycook}/app/helpers/test_helper.rb +0 -0
- data/test/stub/{rails_apps/2.3/mycook → rails2.3-mycook}/app/helpers/uploads_helper.rb +0 -0
- data/test/stub/{rails_apps/2.3/mycook → rails2.3-mycook}/app/helpers/welcome_helper.rb +0 -0
- data/test/stub/{rails_apps/2.3/mycook → rails2.3-mycook}/app/views/layouts/default.rhtml +0 -0
- data/test/stub/{rails_apps/2.3/mycook → rails2.3-mycook}/app/views/recipes/create.rhtml +0 -0
- data/test/stub/{rails_apps/2.3/mycook → rails2.3-mycook}/app/views/recipes/index.rhtml +0 -0
- data/test/stub/{rails_apps/2.3/mycook → rails2.3-mycook}/app/views/recipes/new.rhtml +0 -0
- data/test/stub/{rails_apps/2.3/mycook → rails2.3-mycook}/app/views/uploads/index.rhtml +0 -0
- data/test/stub/{rails_apps/2.3/mycook → rails2.3-mycook}/app/views/uploads/new.html.erb +0 -0
- data/test/stub/{rails_apps/2.3/mycook → rails2.3-mycook}/app/views/welcome/cached.rhtml +0 -0
- data/test/stub/{rails_apps/2.3/mycook → rails2.3-mycook}/app/views/welcome/index.rhtml +0 -0
- data/test/stub/{rails_apps/2.3/mycook → rails2.3-mycook}/config/boot.rb +0 -0
- data/test/stub/{rails_apps/2.3/mycook → rails2.3-mycook}/config/database.yml +0 -0
- data/test/stub/{rails_apps/2.3/mycook → rails2.3-mycook}/config/environment.rb +0 -0
- data/test/stub/{rails_apps/2.0/empty → rails2.3-mycook}/config/environments/development.rb +0 -0
- data/test/stub/{rails_apps/2.3/mycook → rails2.3-mycook}/config/environments/production.rb +0 -0
- data/test/stub/{rails_apps/2.0/empty → rails2.3-mycook}/config/initializers/inflections.rb +0 -0
- data/test/stub/{rails_apps/2.0/empty → rails2.3-mycook}/config/initializers/mime_types.rb +0 -0
- data/test/stub/{rails_apps/2.3/mycook → rails2.3-mycook}/config/routes.rb +0 -0
- data/test/stub/{rails_apps/2.3/mycook → rails2.3-mycook}/log/useless.txt +0 -0
- data/test/stub/{rails_apps/2.3/mycook → rails2.3-mycook}/public/.htaccess +0 -0
- data/test/stub/{rails_apps/1.2/empty → rails2.3-mycook}/public/404.html +0 -0
- data/test/stub/{rails_apps/2.0/empty → rails2.3-mycook}/public/422.html +0 -0
- data/test/stub/{rails_apps/2.0/empty → rails2.3-mycook}/public/500.html +0 -0
- data/test/stub/{rails_apps/2.3/mycook → rails2.3-mycook}/public/dispatch.cgi +0 -0
- data/test/stub/{rails_apps/2.3/mycook → rails2.3-mycook}/public/dispatch.fcgi +0 -0
- data/test/stub/{rails_apps/2.3/mycook → rails2.3-mycook}/public/dispatch.rb +0 -0
- data/test/stub/{rails_apps/1.2/empty → rails2.3-mycook}/public/favicon.ico +0 -0
- data/test/stub/{rails_apps/2.3/mycook → rails2.3-mycook}/public/images/angrywizard.gif +0 -0
- data/test/stub/{rails_apps/2.3/mycook → rails2.3-mycook}/public/images/cookbook.gif +0 -0
- data/test/stub/{rails_apps/2.3/mycook → rails2.3-mycook}/public/images/header.png +0 -0
- data/test/stub/{rails_apps/1.2/empty → rails2.3-mycook}/public/images/rails.png +0 -0
- data/test/stub/{rails_apps/2.0/empty → rails2.3-mycook}/public/robots.txt +0 -0
- data/test/stub/{rails_apps/2.3/mycook → rails2.3-mycook}/public/uploads.html +0 -0
- data/test/stub/{rails_apps/1.2/empty/db → rails2.3-mycook/public/uploads}/.gitignore +0 -0
- data/test/stub/{rails_apps/2.3/mycook → rails2.3-mycook}/public/welcome/cached.html +0 -0
- data/test/stub/{rails_apps/2.0/empty → rails2.3-mycook}/script/about +0 -0
- data/test/stub/{rails_apps/2.0/empty → rails2.3-mycook}/script/console +0 -0
- data/test/stub/{rails_apps/2.2/empty → rails2.3-mycook}/script/dbconsole +0 -0
- data/test/stub/{rails_apps/2.0/empty → rails2.3-mycook}/script/destroy +0 -0
- data/test/stub/{rails_apps/2.0/empty → rails2.3-mycook}/script/generate +0 -0
- data/test/stub/{rails_apps/1.2/empty → rails2.3-mycook}/script/performance/benchmarker +0 -0
- data/test/stub/{rails_apps/1.2/empty → rails2.3-mycook}/script/performance/profiler +0 -0
- data/test/stub/{rails_apps/2.0/empty → rails2.3-mycook}/script/performance/request +0 -0
- data/test/stub/{rails_apps/2.0/empty → rails2.3-mycook}/script/plugin +0 -0
- data/test/stub/{rails_apps/1.2/empty → rails2.3-mycook}/script/process/inspector +0 -0
- data/test/stub/{rails_apps/1.2/empty → rails2.3-mycook}/script/process/reaper +0 -0
- data/test/stub/{rails_apps/1.2/empty → rails2.3-mycook}/script/process/spawner +0 -0
- data/test/stub/{rails_apps/2.0/empty → rails2.3-mycook}/script/runner +0 -0
- data/test/stub/{rails_apps/2.0/empty → rails2.3-mycook}/script/server +0 -0
- data/test/stub/{rails_apps/2.3/mycook → rails2.3-mycook}/sites/some.site/public/uploads.html +0 -0
- data/test/stub/{rails_apps/2.3/mycook → rails2.3-mycook}/sites/some.site/public/welcome/cached.html +0 -0
- data/test/stub/{rails_apps/2.3/mycook → rails2.3-mycook}/tmp/cache/useless.txt +0 -0
- data/test/stub/{rails_apps/2.3/mycook → rails2.3-mycook}/tmp/pids/useless.txt +0 -0
- data/test/stub/{rails_apps/2.3/mycook → rails2.3-mycook}/tmp/sessions/useless.txt +0 -0
- data/test/stub/{rails_apps/2.3/mycook → rails2.3-mycook}/tmp/sockets/useless.txt +0 -0
- data/test/stub/rails2.3/app/controllers/foo_controller.rb +1 -1
- data/test/stub/rails2.3/config/routes.rb +1 -2
- data/test/stub/wsgi/passenger_wsgi.py +47 -8
- data/test/stub/{rails_apps/1.2/empty/public/stylesheets → wsgi/public}/.gitignore +0 -0
- data/test/support/apache2_controller.rb +2 -2
- data/test/support/nginx_controller.rb +11 -5
- data/test/support/placebo-preloader.rb +2 -2
- data/test/support/test_helper.rb +26 -7
- metadata +78 -240
- metadata.gz.asc +7 -7
- data/debian.template/repack.sh +0 -42
- data/debian.template/watch +0 -3
- data/test/integration_tests/cgi_environment_spec.rb +0 -36
- data/test/integration_tests/hello_world_rack_spec.rb +0 -43
- data/test/integration_tests/hello_world_wsgi_spec.rb +0 -41
- data/test/integration_tests/mycook_spec.rb +0 -166
- data/test/stub/rack/public/rack.jpg +0 -0
- data/test/stub/rails_apps/1.2/empty/.gitignore +0 -3
- data/test/stub/rails_apps/1.2/empty/app/controllers/application.rb +0 -7
- data/test/stub/rails_apps/1.2/empty/config/boot.rb +0 -108
- data/test/stub/rails_apps/1.2/empty/config/database.yml +0 -31
- data/test/stub/rails_apps/1.2/empty/config/environment.rb +0 -66
- data/test/stub/rails_apps/1.2/empty/config/environments/development.rb +0 -21
- data/test/stub/rails_apps/1.2/empty/config/environments/production.rb +0 -18
- data/test/stub/rails_apps/1.2/empty/config/environments/staging.rb +0 -18
- data/test/stub/rails_apps/1.2/empty/config/environments/test.rb +0 -19
- data/test/stub/rails_apps/1.2/empty/config/routes.rb +0 -23
- data/test/stub/rails_apps/1.2/empty/doc/README_FOR_APP +0 -2
- data/test/stub/rails_apps/1.2/empty/public/.htaccess +0 -40
- data/test/stub/rails_apps/1.2/empty/public/500.html +0 -30
- data/test/stub/rails_apps/1.2/empty/public/dispatch.cgi +0 -10
- data/test/stub/rails_apps/1.2/empty/public/dispatch.fcgi +0 -24
- data/test/stub/rails_apps/1.2/empty/public/dispatch.rb +0 -10
- data/test/stub/rails_apps/1.2/empty/public/robots.txt +0 -1
- data/test/stub/rails_apps/1.2/empty/script/about +0 -3
- data/test/stub/rails_apps/1.2/empty/script/breakpointer +0 -3
- data/test/stub/rails_apps/1.2/empty/script/console +0 -3
- data/test/stub/rails_apps/1.2/empty/script/destroy +0 -3
- data/test/stub/rails_apps/1.2/empty/script/generate +0 -3
- data/test/stub/rails_apps/1.2/empty/script/plugin +0 -3
- data/test/stub/rails_apps/1.2/empty/script/runner +0 -3
- data/test/stub/rails_apps/1.2/empty/script/server +0 -3
- data/test/stub/rails_apps/1.2/empty/test/test_helper.rb +0 -28
- data/test/stub/rails_apps/2.0/empty/.gitignore +0 -3
- data/test/stub/rails_apps/2.0/empty/Rakefile +0 -10
- data/test/stub/rails_apps/2.0/empty/app/controllers/application.rb +0 -10
- data/test/stub/rails_apps/2.0/empty/app/helpers/application_helper.rb +0 -3
- data/test/stub/rails_apps/2.0/empty/app/models/.gitignore +0 -0
- data/test/stub/rails_apps/2.0/empty/config/boot.rb +0 -108
- data/test/stub/rails_apps/2.0/empty/config/database.yml +0 -31
- data/test/stub/rails_apps/2.0/empty/config/environment.rb +0 -59
- data/test/stub/rails_apps/2.0/empty/config/environments/production.rb +0 -18
- data/test/stub/rails_apps/2.0/empty/config/environments/staging.rb +0 -18
- data/test/stub/rails_apps/2.0/empty/config/environments/test.rb +0 -22
- data/test/stub/rails_apps/2.0/empty/config/routes.rb +0 -35
- data/test/stub/rails_apps/2.0/empty/db/.gitignore +0 -0
- data/test/stub/rails_apps/2.0/empty/doc/README_FOR_APP +0 -2
- data/test/stub/rails_apps/2.0/empty/public/.htaccess +0 -40
- data/test/stub/rails_apps/2.0/empty/public/404.html +0 -30
- data/test/stub/rails_apps/2.0/empty/public/dispatch.cgi +0 -10
- data/test/stub/rails_apps/2.0/empty/public/dispatch.fcgi +0 -24
- data/test/stub/rails_apps/2.0/empty/public/dispatch.rb +0 -10
- data/test/stub/rails_apps/2.0/empty/public/favicon.ico +0 -0
- data/test/stub/rails_apps/2.0/empty/public/images/rails.png +0 -0
- data/test/stub/rails_apps/2.0/empty/public/stylesheets/.gitignore +0 -0
- data/test/stub/rails_apps/2.0/empty/script/performance/benchmarker +0 -3
- data/test/stub/rails_apps/2.0/empty/script/performance/profiler +0 -3
- data/test/stub/rails_apps/2.0/empty/script/process/inspector +0 -3
- data/test/stub/rails_apps/2.0/empty/script/process/reaper +0 -3
- data/test/stub/rails_apps/2.0/empty/script/process/spawner +0 -3
- data/test/stub/rails_apps/2.0/empty/test/test_helper.rb +0 -38
- data/test/stub/rails_apps/2.2/empty/.gitignore +0 -3
- data/test/stub/rails_apps/2.2/empty/Rakefile +0 -10
- data/test/stub/rails_apps/2.2/empty/app/controllers/application.rb +0 -15
- data/test/stub/rails_apps/2.2/empty/app/helpers/application_helper.rb +0 -3
- data/test/stub/rails_apps/2.2/empty/app/models/.gitignore +0 -0
- data/test/stub/rails_apps/2.2/empty/config/boot.rb +0 -109
- data/test/stub/rails_apps/2.2/empty/config/database.yml +0 -31
- data/test/stub/rails_apps/2.2/empty/config/environment.rb +0 -75
- data/test/stub/rails_apps/2.2/empty/config/environments/development.rb +0 -17
- data/test/stub/rails_apps/2.2/empty/config/environments/production.rb +0 -24
- data/test/stub/rails_apps/2.2/empty/config/environments/staging.rb +0 -24
- data/test/stub/rails_apps/2.2/empty/config/environments/test.rb +0 -22
- data/test/stub/rails_apps/2.2/empty/config/initializers/inflections.rb +0 -10
- data/test/stub/rails_apps/2.2/empty/config/initializers/mime_types.rb +0 -5
- data/test/stub/rails_apps/2.2/empty/config/initializers/new_rails_defaults.rb +0 -17
- data/test/stub/rails_apps/2.2/empty/config/locales/en.yml +0 -5
- data/test/stub/rails_apps/2.2/empty/config/routes.rb +0 -43
- data/test/stub/rails_apps/2.2/empty/db/.gitignore +0 -0
- data/test/stub/rails_apps/2.2/empty/doc/README_FOR_APP +0 -5
- data/test/stub/rails_apps/2.2/empty/public/404.html +0 -30
- data/test/stub/rails_apps/2.2/empty/public/422.html +0 -30
- data/test/stub/rails_apps/2.2/empty/public/500.html +0 -33
- data/test/stub/rails_apps/2.2/empty/public/dispatch.cgi +0 -10
- data/test/stub/rails_apps/2.2/empty/public/dispatch.fcgi +0 -24
- data/test/stub/rails_apps/2.2/empty/public/dispatch.rb +0 -10
- data/test/stub/rails_apps/2.2/empty/public/favicon.ico +0 -0
- data/test/stub/rails_apps/2.2/empty/public/images/rails.png +0 -0
- data/test/stub/rails_apps/2.2/empty/public/robots.txt +0 -5
- data/test/stub/rails_apps/2.2/empty/public/stylesheets/.gitignore +0 -0
- data/test/stub/rails_apps/2.2/empty/script/about +0 -4
- data/test/stub/rails_apps/2.2/empty/script/console +0 -3
- data/test/stub/rails_apps/2.2/empty/script/destroy +0 -3
- data/test/stub/rails_apps/2.2/empty/script/generate +0 -3
- data/test/stub/rails_apps/2.2/empty/script/performance/benchmarker +0 -3
- data/test/stub/rails_apps/2.2/empty/script/performance/profiler +0 -3
- data/test/stub/rails_apps/2.2/empty/script/performance/request +0 -3
- data/test/stub/rails_apps/2.2/empty/script/plugin +0 -3
- data/test/stub/rails_apps/2.2/empty/script/process/inspector +0 -3
- data/test/stub/rails_apps/2.2/empty/script/process/reaper +0 -3
- data/test/stub/rails_apps/2.2/empty/script/process/spawner +0 -3
- data/test/stub/rails_apps/2.2/empty/script/runner +0 -3
- data/test/stub/rails_apps/2.2/empty/script/server +0 -3
- data/test/stub/rails_apps/2.2/empty/test/performance/browsing_test.rb +0 -9
- data/test/stub/rails_apps/2.2/empty/test/test_helper.rb +0 -38
- data/test/stub/rails_apps/2.3/empty/.gitignore +0 -3
- data/test/stub/rails_apps/2.3/empty/Rakefile +0 -10
- data/test/stub/rails_apps/2.3/empty/app/controllers/application_controller.rb +0 -10
- data/test/stub/rails_apps/2.3/empty/app/helpers/application_helper.rb +0 -3
- data/test/stub/rails_apps/2.3/empty/app/models/.gitignore +0 -0
- data/test/stub/rails_apps/2.3/empty/config/boot.rb +0 -110
- data/test/stub/rails_apps/2.3/empty/config/database.yml +0 -31
- data/test/stub/rails_apps/2.3/empty/config/environment.rb +0 -41
- data/test/stub/rails_apps/2.3/empty/config/environments/development.rb +0 -17
- data/test/stub/rails_apps/2.3/empty/config/environments/production.rb +0 -28
- data/test/stub/rails_apps/2.3/empty/config/environments/staging.rb +0 -28
- data/test/stub/rails_apps/2.3/empty/config/environments/test.rb +0 -28
- data/test/stub/rails_apps/2.3/empty/config/initializers/backtrace_silencers.rb +0 -7
- data/test/stub/rails_apps/2.3/empty/config/initializers/inflections.rb +0 -10
- data/test/stub/rails_apps/2.3/empty/config/initializers/mime_types.rb +0 -5
- data/test/stub/rails_apps/2.3/empty/config/initializers/new_rails_defaults.rb +0 -21
- data/test/stub/rails_apps/2.3/empty/config/initializers/session_store.rb +0 -15
- data/test/stub/rails_apps/2.3/empty/config/locales/en.yml +0 -5
- data/test/stub/rails_apps/2.3/empty/config/routes.rb +0 -43
- data/test/stub/rails_apps/2.3/empty/db/.gitignore +0 -0
- data/test/stub/rails_apps/2.3/empty/db/seeds.rb +0 -7
- data/test/stub/rails_apps/2.3/empty/doc/README_FOR_APP +0 -2
- data/test/stub/rails_apps/2.3/empty/public/404.html +0 -30
- data/test/stub/rails_apps/2.3/empty/public/422.html +0 -30
- data/test/stub/rails_apps/2.3/empty/public/500.html +0 -30
- data/test/stub/rails_apps/2.3/empty/public/favicon.ico +0 -0
- data/test/stub/rails_apps/2.3/empty/public/images/rails.png +0 -0
- data/test/stub/rails_apps/2.3/empty/public/robots.txt +0 -5
- data/test/stub/rails_apps/2.3/empty/public/stylesheets/.gitignore +0 -0
- data/test/stub/rails_apps/2.3/empty/script/about +0 -4
- data/test/stub/rails_apps/2.3/empty/script/console +0 -3
- data/test/stub/rails_apps/2.3/empty/script/dbconsole +0 -3
- data/test/stub/rails_apps/2.3/empty/script/destroy +0 -3
- data/test/stub/rails_apps/2.3/empty/script/generate +0 -3
- data/test/stub/rails_apps/2.3/empty/script/performance/benchmarker +0 -3
- data/test/stub/rails_apps/2.3/empty/script/performance/profiler +0 -3
- data/test/stub/rails_apps/2.3/empty/script/plugin +0 -3
- data/test/stub/rails_apps/2.3/empty/script/runner +0 -3
- data/test/stub/rails_apps/2.3/empty/script/server +0 -3
- data/test/stub/rails_apps/2.3/empty/test/performance/browsing_test.rb +0 -9
- data/test/stub/rails_apps/2.3/empty/test/test_helper.rb +0 -38
- data/test/stub/rails_apps/2.3/mycook/Rakefile +0 -10
- data/test/stub/rails_apps/2.3/mycook/app/helpers/application_helper.rb +0 -3
- data/test/stub/rails_apps/2.3/mycook/config/environments/development.rb +0 -18
- data/test/stub/rails_apps/2.3/mycook/config/initializers/inflections.rb +0 -10
- data/test/stub/rails_apps/2.3/mycook/config/initializers/mime_types.rb +0 -5
- data/test/stub/rails_apps/2.3/mycook/public/404.html +0 -30
- data/test/stub/rails_apps/2.3/mycook/public/422.html +0 -30
- data/test/stub/rails_apps/2.3/mycook/public/500.html +0 -30
- data/test/stub/rails_apps/2.3/mycook/public/favicon.ico +0 -0
- data/test/stub/rails_apps/2.3/mycook/public/images/rails.png +0 -0
- data/test/stub/rails_apps/2.3/mycook/public/robots.txt +0 -5
- data/test/stub/rails_apps/2.3/mycook/public/uploads/.gitignore +0 -0
- data/test/stub/rails_apps/2.3/mycook/script/about +0 -3
- data/test/stub/rails_apps/2.3/mycook/script/console +0 -3
- data/test/stub/rails_apps/2.3/mycook/script/dbconsole +0 -3
- data/test/stub/rails_apps/2.3/mycook/script/destroy +0 -3
- data/test/stub/rails_apps/2.3/mycook/script/generate +0 -3
- data/test/stub/rails_apps/2.3/mycook/script/performance/benchmarker +0 -3
- data/test/stub/rails_apps/2.3/mycook/script/performance/profiler +0 -3
- data/test/stub/rails_apps/2.3/mycook/script/performance/request +0 -3
- data/test/stub/rails_apps/2.3/mycook/script/plugin +0 -3
- data/test/stub/rails_apps/2.3/mycook/script/process/inspector +0 -3
- data/test/stub/rails_apps/2.3/mycook/script/process/reaper +0 -3
- data/test/stub/rails_apps/2.3/mycook/script/process/spawner +0 -3
- data/test/stub/rails_apps/2.3/mycook/script/runner +0 -3
- data/test/stub/rails_apps/2.3/mycook/script/server +0 -3
- data/test/stub/wsgi/public/wsgi-snake.jpg +0 -0
@@ -345,6 +345,7 @@ Group::Group(const SuperGroupPtr &_superGroup, const Options &options, const Com
|
|
345
345
|
disabledCount = 0;
|
346
346
|
spawner = getPool()->spawnerFactory->create(options);
|
347
347
|
restartsInitiated = 0;
|
348
|
+
processesBeingSpawned = 0;
|
348
349
|
m_spawning = false;
|
349
350
|
m_restarting = false;
|
350
351
|
lifeStatus = ALIVE;
|
@@ -419,13 +420,13 @@ Group::onSessionClose(const ProcessPtr &process, Session *session) {
|
|
419
420
|
|| process->enabled == Process::DISABLING
|
420
421
|
|| process->enabled == Process::DETACHED);
|
421
422
|
if (process->enabled == Process::ENABLED) {
|
422
|
-
pqueue.decrease(process->pqHandle, process->
|
423
|
+
pqueue.decrease(process->pqHandle, process->busyness());
|
423
424
|
}
|
424
425
|
|
425
|
-
/* This group now has a process that's guaranteed to be not
|
426
|
-
*
|
426
|
+
/* This group now has a process that's guaranteed to be not
|
427
|
+
* totally busy.
|
427
428
|
*/
|
428
|
-
assert(!process->
|
429
|
+
assert(!process->isTotallyBusy());
|
429
430
|
|
430
431
|
bool detachingBecauseOfMaxRequests = false;
|
431
432
|
bool detachingBecauseCapacityNeeded = false;
|
@@ -459,8 +460,8 @@ Group::onSessionClose(const ProcessPtr &process, Session *session) {
|
|
459
460
|
* checked conditions) then now's a good time to detach
|
460
461
|
* this process or group in order to free capacity.
|
461
462
|
*/
|
462
|
-
P_DEBUG("Process " << process->inspect() << " is no longer
|
463
|
-
"
|
463
|
+
P_DEBUG("Process " << process->inspect() << " is no longer totally "
|
464
|
+
"busy; detaching it in order to make room in the pool");
|
464
465
|
} else {
|
465
466
|
/* This process has processed its maximum number of requests,
|
466
467
|
* so we detach it.
|
@@ -848,19 +849,31 @@ Group::spawnThreadRealMain(const SpawnerPtr &spawner, const Options &options, un
|
|
848
849
|
|
849
850
|
verifyInvariants();
|
850
851
|
assert(m_spawning);
|
852
|
+
assert(processesBeingSpawned > 0);
|
853
|
+
|
854
|
+
processesBeingSpawned--;
|
855
|
+
assert(processesBeingSpawned == 0);
|
851
856
|
|
852
857
|
UPDATE_TRACE_POINT();
|
853
858
|
vector<Callback> actions;
|
854
859
|
if (process != NULL) {
|
855
|
-
attach(process, actions);
|
856
|
-
|
857
|
-
|
858
|
-
|
860
|
+
AttachResult result = attach(process, actions);
|
861
|
+
if (result == AR_OK) {
|
862
|
+
guard.clear();
|
863
|
+
if (getWaitlist.empty()) {
|
864
|
+
pool->assignSessionsToGetWaiters(actions);
|
865
|
+
} else {
|
866
|
+
assignSessionsToGetWaiters(actions);
|
867
|
+
}
|
868
|
+
P_DEBUG("New process count = " << enabledCount <<
|
869
|
+
", remaining get waiters = " << getWaitlist.size());
|
859
870
|
} else {
|
860
|
-
|
871
|
+
done = true;
|
872
|
+
P_DEBUG("Unable to attach spawned process " << process->inspect());
|
873
|
+
if (result == AR_ANOTHER_GROUP_IS_WAITING_FOR_CAPACITY) {
|
874
|
+
pool->possiblySpawnMoreProcessesForExistingGroups();
|
875
|
+
}
|
861
876
|
}
|
862
|
-
P_DEBUG("New process count = " << enabledCount <<
|
863
|
-
", remaining get waiters = " << getWaitlist.size());
|
864
877
|
} else {
|
865
878
|
// TODO: sure this is the best thing? if there are
|
866
879
|
// processes currently alive we should just use them.
|
@@ -875,22 +888,18 @@ Group::spawnThreadRealMain(const SpawnerPtr &spawner, const Options &options, un
|
|
875
888
|
done = true;
|
876
889
|
}
|
877
890
|
|
878
|
-
// Temporarily mark this Group as 'not spawning' so
|
879
|
-
// that pool->utilization() doesn't take this thread's spawning
|
880
|
-
// state into account.
|
881
|
-
m_spawning = false;
|
882
|
-
|
883
891
|
done = done
|
884
|
-
|| (
|
885
|
-
|| (
|
892
|
+
|| (processLowerLimitsSatisfied() && getWaitlist.empty())
|
893
|
+
|| processUpperLimitsReached()
|
886
894
|
|| pool->atFullCapacity(false);
|
887
895
|
m_spawning = !done;
|
888
896
|
if (done) {
|
889
897
|
P_DEBUG("Spawn loop done");
|
890
898
|
} else {
|
899
|
+
processesBeingSpawned++;
|
891
900
|
P_DEBUG("Continue spawning");
|
892
901
|
}
|
893
|
-
|
902
|
+
|
894
903
|
UPDATE_TRACE_POINT();
|
895
904
|
pool->fullVerifyInvariants();
|
896
905
|
lock.unlock();
|
@@ -908,8 +917,9 @@ bool
|
|
908
917
|
Group::shouldSpawn() const {
|
909
918
|
return allowSpawn()
|
910
919
|
&& (
|
911
|
-
(
|
912
|
-
|| (
|
920
|
+
!processLowerLimitsSatisfied()
|
921
|
+
|| allEnabledProcessesAreTotallyBusy()
|
922
|
+
|| !getWaitlist.empty()
|
913
923
|
);
|
914
924
|
}
|
915
925
|
|
@@ -918,15 +928,8 @@ Group::shouldSpawnForGetAction() const {
|
|
918
928
|
return enabledCount == 0 || shouldSpawn();
|
919
929
|
}
|
920
930
|
|
921
|
-
bool
|
922
|
-
Group::allowSpawn() const {
|
923
|
-
return isAlive()
|
924
|
-
&& !poolAtFullCapacity()
|
925
|
-
&& (options.maxProcesses == 0 || getProcessCount() < options.maxProcesses);
|
926
|
-
}
|
927
|
-
|
928
931
|
void
|
929
|
-
Group::restart(const Options &options) {
|
932
|
+
Group::restart(const Options &options, RestartMethod method) {
|
930
933
|
vector<Callback> actions;
|
931
934
|
|
932
935
|
assert(isAlive());
|
@@ -936,13 +939,14 @@ Group::restart(const Options &options) {
|
|
936
939
|
// the following tells them to abort their current work as soon as possible.
|
937
940
|
restartsInitiated++;
|
938
941
|
|
939
|
-
|
942
|
+
processesBeingSpawned = 0;
|
943
|
+
m_spawning = false;
|
940
944
|
m_restarting = true;
|
941
945
|
detachAll(actions);
|
942
946
|
getPool()->interruptableThreads.create_thread(
|
943
947
|
boost::bind(&Group::finalizeRestart, this, shared_from_this(),
|
944
948
|
options.copyAndPersist().clearPerRequestFields(),
|
945
|
-
getPool()->spawnerFactory, restartsInitiated, actions),
|
949
|
+
method, getPool()->spawnerFactory, restartsInitiated, actions),
|
946
950
|
"Group restarter: " + name,
|
947
951
|
POOL_HELPER_THREAD_STACK_SIZE
|
948
952
|
);
|
@@ -950,8 +954,9 @@ Group::restart(const Options &options) {
|
|
950
954
|
|
951
955
|
// The 'self' parameter is for keeping the current Group object alive while this thread is running.
|
952
956
|
void
|
953
|
-
Group::finalizeRestart(GroupPtr self, Options options,
|
954
|
-
unsigned int restartsInitiated,
|
957
|
+
Group::finalizeRestart(GroupPtr self, Options options, RestartMethod method,
|
958
|
+
SpawnerFactoryPtr spawnerFactory, unsigned int restartsInitiated,
|
959
|
+
vector<Callback> postLockActions)
|
955
960
|
{
|
956
961
|
TRACE_POINT();
|
957
962
|
|
@@ -1003,13 +1008,23 @@ Group::finalizeRestart(GroupPtr self, Options options, SpawnerFactoryPtr spawner
|
|
1003
1008
|
spawner = newSpawner;
|
1004
1009
|
|
1005
1010
|
m_restarting = false;
|
1006
|
-
if (
|
1011
|
+
if (shouldSpawn()) {
|
1007
1012
|
spawn();
|
1013
|
+
} else if (isWaitingForCapacity()) {
|
1014
|
+
P_INFO("Group " << name << " is waiting for capacity to become available. "
|
1015
|
+
"Trying to shutdown another idle process to free capacity...");
|
1016
|
+
if (pool->forceFreeCapacity(this, postLockActions) != NULL) {
|
1017
|
+
spawn();
|
1018
|
+
} else {
|
1019
|
+
P_INFO("There are no processes right now that are eligible "
|
1020
|
+
"for shutdown. Will try again later.");
|
1021
|
+
}
|
1008
1022
|
}
|
1009
1023
|
verifyInvariants();
|
1010
1024
|
|
1011
1025
|
l.unlock();
|
1012
1026
|
oldSpawner.reset();
|
1027
|
+
Pool::runAllActions(postLockActions);
|
1013
1028
|
P_DEBUG("Restart of group " << name << " done");
|
1014
1029
|
if (debug != NULL && debug->restarting) {
|
1015
1030
|
debug->debugger->send("Restarting done");
|
@@ -1143,21 +1158,28 @@ Group::poolAtFullCapacity() const {
|
|
1143
1158
|
|
1144
1159
|
bool
|
1145
1160
|
Group::anotherGroupIsWaitingForCapacity() const {
|
1161
|
+
return findOtherGroupWaitingForCapacity() != NULL;
|
1162
|
+
}
|
1163
|
+
|
1164
|
+
boost::shared_ptr<Group>
|
1165
|
+
Group::findOtherGroupWaitingForCapacity() const {
|
1146
1166
|
PoolPtr pool = getPool();
|
1147
1167
|
StringMap<SuperGroupPtr>::const_iterator sg_it, sg_end = pool->superGroups.end();
|
1148
1168
|
for (sg_it = pool->superGroups.begin(); sg_it != sg_end; sg_it++) {
|
1149
1169
|
pair<StaticString, SuperGroupPtr> p = *sg_it;
|
1150
|
-
|
1151
|
-
|
1152
|
-
|
1153
|
-
|
1154
|
-
&& !group->getWaitlist.empty())
|
1155
|
-
{
|
1156
|
-
return true;
|
1170
|
+
vector<GroupPtr>::const_iterator g_it, g_end = p.second->groups.end();
|
1171
|
+
for (g_it = p.second->groups.begin(); g_it != g_end; g_it++) {
|
1172
|
+
if (g_it->get() != this && (*g_it)->isWaitingForCapacity()) {
|
1173
|
+
return *g_it;
|
1157
1174
|
}
|
1158
1175
|
}
|
1159
1176
|
}
|
1160
|
-
return
|
1177
|
+
return GroupPtr();
|
1178
|
+
}
|
1179
|
+
|
1180
|
+
ProcessPtr
|
1181
|
+
Group::poolForceFreeCapacity(const Group *exclude, vector<Callback> &postLockActions) {
|
1182
|
+
return getPool()->forceFreeCapacity(exclude, postLockActions);
|
1161
1183
|
}
|
1162
1184
|
|
1163
1185
|
bool
|
@@ -391,11 +391,6 @@ public:
|
|
391
391
|
*/
|
392
392
|
bool noop;
|
393
393
|
|
394
|
-
/** Specifies whether, if the pool is already full, the pool is allowed to
|
395
|
-
* trash a non-idle process in order to free capacity. True by default.
|
396
|
-
*/
|
397
|
-
bool allowTrashingNonIdleProcesses;
|
398
|
-
|
399
394
|
/*-----------------*/
|
400
395
|
/*-----------------*/
|
401
396
|
|
@@ -441,8 +436,7 @@ public:
|
|
441
436
|
statThrottleRate = 0;
|
442
437
|
maxRequests = 0;
|
443
438
|
noop = false;
|
444
|
-
|
445
|
-
|
439
|
+
|
446
440
|
/*********************************/
|
447
441
|
}
|
448
442
|
|
@@ -27,6 +27,7 @@
|
|
27
27
|
|
28
28
|
#include <string>
|
29
29
|
#include <vector>
|
30
|
+
#include <algorithm>
|
30
31
|
#include <utility>
|
31
32
|
#include <sstream>
|
32
33
|
#include <iomanip>
|
@@ -165,7 +166,7 @@ public:
|
|
165
166
|
*
|
166
167
|
* - A process has been spawned but its associated group has
|
167
168
|
* no get waiters. This process can be killed and the resulting
|
168
|
-
* free capacity will be used to
|
169
|
+
* free capacity will be used to spawn a process for this
|
169
170
|
* get request.
|
170
171
|
* - A process (that has apparently been spawned after getWaitlist
|
171
172
|
* was populated) is done processing a request. This process can
|
@@ -268,7 +269,15 @@ public:
|
|
268
269
|
}
|
269
270
|
}
|
270
271
|
|
271
|
-
|
272
|
+
static const char *maybePluralize(unsigned int count, const char *singular, const char *plural) {
|
273
|
+
if (count == 1) {
|
274
|
+
return singular;
|
275
|
+
} else {
|
276
|
+
return plural;
|
277
|
+
}
|
278
|
+
}
|
279
|
+
|
280
|
+
ProcessPtr findOldestIdleProcess(const Group *exclude = NULL) const {
|
272
281
|
ProcessPtr oldestIdleProcess;
|
273
282
|
|
274
283
|
SuperGroupMap::const_iterator it, end = superGroups.end();
|
@@ -278,11 +287,14 @@ public:
|
|
278
287
|
vector<GroupPtr>::const_iterator g_it, g_end = groups.end();
|
279
288
|
for (g_it = groups.begin(); g_it != g_end; g_it++) {
|
280
289
|
const GroupPtr &group = *g_it;
|
290
|
+
if (group.get() == exclude) {
|
291
|
+
continue;
|
292
|
+
}
|
281
293
|
const ProcessList &processes = group->enabledProcesses;
|
282
294
|
ProcessList::const_iterator p_it, p_end = processes.end();
|
283
295
|
for (p_it = processes.begin(); p_it != p_end; p_it++) {
|
284
296
|
const ProcessPtr process = *p_it;
|
285
|
-
if (process->
|
297
|
+
if (process->busyness() == 0
|
286
298
|
&& (oldestIdleProcess == NULL
|
287
299
|
|| process->lastUsed < oldestIdleProcess->lastUsed)
|
288
300
|
) {
|
@@ -328,13 +340,14 @@ public:
|
|
328
340
|
bool done = false;
|
329
341
|
vector<GetWaiter>::iterator it, end = getWaitlist.end();
|
330
342
|
vector<GetWaiter> newWaitlist;
|
331
|
-
|
343
|
+
|
332
344
|
for (it = getWaitlist.begin(); it != end && !done; it++) {
|
333
345
|
GetWaiter &waiter = *it;
|
334
|
-
|
346
|
+
|
335
347
|
SuperGroup *superGroup = findMatchingSuperGroup(waiter.options);
|
336
348
|
if (superGroup != NULL) {
|
337
|
-
SessionPtr session = superGroup->get(waiter.options, waiter.callback
|
349
|
+
SessionPtr session = superGroup->get(waiter.options, waiter.callback,
|
350
|
+
postLockActions);
|
338
351
|
if (session != NULL) {
|
339
352
|
postLockActions.push_back(boost::bind(
|
340
353
|
waiter.callback, session, ExceptionPtr()));
|
@@ -343,7 +356,8 @@ public:
|
|
343
356
|
* the group's get wait list.
|
344
357
|
*/
|
345
358
|
} else if (!atFullCapacity(false)) {
|
346
|
-
createSuperGroupAndAsyncGetFromIt(waiter.options, waiter.callback
|
359
|
+
createSuperGroupAndAsyncGetFromIt(waiter.options, waiter.callback,
|
360
|
+
postLockActions);
|
347
361
|
} else {
|
348
362
|
/* Still cannot satisfy this get request. Keep it on the get
|
349
363
|
* wait list and try again later.
|
@@ -351,8 +365,8 @@ public:
|
|
351
365
|
newWaitlist.push_back(waiter);
|
352
366
|
}
|
353
367
|
}
|
354
|
-
|
355
|
-
getWaitlist
|
368
|
+
|
369
|
+
std::swap(getWaitlist, newWaitlist);
|
356
370
|
}
|
357
371
|
|
358
372
|
template<typename Queue>
|
@@ -409,6 +423,30 @@ public:
|
|
409
423
|
superGroup->getWaitlist.pop_front();
|
410
424
|
}
|
411
425
|
}
|
426
|
+
|
427
|
+
/**
|
428
|
+
* Calls Group::detach() so be sure to fix up the invariants afterwards.
|
429
|
+
* See the comments for Group::detach() and the code for detachProcessUnlocked().
|
430
|
+
*/
|
431
|
+
ProcessPtr forceFreeCapacity(const Group *exclude,
|
432
|
+
vector<Callback> &postLockActions)
|
433
|
+
{
|
434
|
+
ProcessPtr process = findOldestIdleProcess(exclude);
|
435
|
+
if (process != NULL) {
|
436
|
+
P_DEBUG("Forcefully detaching process " << process->inspect() <<
|
437
|
+
" in order to free capacity in the pool");
|
438
|
+
|
439
|
+
const GroupPtr group = process->getGroup();
|
440
|
+
assert(group != NULL);
|
441
|
+
assert(group->getWaitlist.empty());
|
442
|
+
|
443
|
+
const SuperGroupPtr superGroup = group->getSuperGroup();
|
444
|
+
assert(superGroup != NULL);
|
445
|
+
|
446
|
+
group->detach(process, postLockActions);
|
447
|
+
}
|
448
|
+
return process;
|
449
|
+
}
|
412
450
|
|
413
451
|
/**
|
414
452
|
* Forcefully destroys and detaches the given SuperGroup. After detaching
|
@@ -437,7 +475,7 @@ public:
|
|
437
475
|
const SuperGroupPtr superGroup = group->getSuperGroup();
|
438
476
|
assert(superGroup->state != SuperGroup::INITIALIZING);
|
439
477
|
assert(superGroup->getWaitlist.empty());
|
440
|
-
|
478
|
+
|
441
479
|
group->detach(process, postLockActions);
|
442
480
|
// 'process' may now be a stale pointer so don't use it anymore.
|
443
481
|
assignSessionsToGetWaiters(postLockActions);
|
@@ -866,10 +904,11 @@ public:
|
|
866
904
|
}
|
867
905
|
|
868
906
|
SuperGroupPtr createSuperGroupAndAsyncGetFromIt(const Options &options,
|
869
|
-
const GetCallback &callback)
|
907
|
+
const GetCallback &callback, vector<Callback> &postLockActions)
|
870
908
|
{
|
871
909
|
SuperGroupPtr superGroup = createSuperGroup(options);
|
872
|
-
SessionPtr session = superGroup->get(options, callback
|
910
|
+
SessionPtr session = superGroup->get(options, callback,
|
911
|
+
postLockActions);
|
873
912
|
/* Callback should now have been put on the wait list,
|
874
913
|
* unless something has changed and we forgot to update
|
875
914
|
* some code here...
|
@@ -964,17 +1003,18 @@ public:
|
|
964
1003
|
// should never call the callback while holding the lock.
|
965
1004
|
void asyncGet(const Options &options, const GetCallback &callback, bool lockNow = true) {
|
966
1005
|
DynamicScopedLock lock(syncher, lockNow);
|
967
|
-
|
1006
|
+
|
968
1007
|
assert(lifeStatus == ALIVE);
|
969
1008
|
verifyInvariants();
|
970
|
-
P_TRACE(2, "asyncGet(
|
971
|
-
|
1009
|
+
P_TRACE(2, "asyncGet(appGroupName=" << options.getAppGroupName() << ")");
|
1010
|
+
vector<Callback> actions;
|
1011
|
+
|
972
1012
|
SuperGroup *existingSuperGroup = findMatchingSuperGroup(options);
|
973
1013
|
if (OXT_LIKELY(existingSuperGroup != NULL)) {
|
974
1014
|
/* Best case: the app super group is already in the pool. Let's use it. */
|
975
1015
|
P_TRACE(2, "Found existing SuperGroup");
|
976
1016
|
existingSuperGroup->verifyInvariants();
|
977
|
-
SessionPtr session = existingSuperGroup->get(options, callback);
|
1017
|
+
SessionPtr session = existingSuperGroup->get(options, callback, actions);
|
978
1018
|
existingSuperGroup->verifyInvariants();
|
979
1019
|
verifyInvariants();
|
980
1020
|
P_TRACE(2, "asyncGet() finished");
|
@@ -990,36 +1030,21 @@ public:
|
|
990
1030
|
* resources to make a new one.
|
991
1031
|
*/
|
992
1032
|
P_DEBUG("Spawning new SuperGroup");
|
993
|
-
SuperGroupPtr superGroup = createSuperGroupAndAsyncGetFromIt(options,
|
1033
|
+
SuperGroupPtr superGroup = createSuperGroupAndAsyncGetFromIt(options,
|
1034
|
+
callback, actions);
|
994
1035
|
superGroup->verifyInvariants();
|
995
1036
|
verifyInvariants();
|
996
1037
|
P_DEBUG("asyncGet() finished");
|
997
1038
|
|
998
1039
|
} else {
|
999
|
-
vector<Callback> actions;
|
1000
|
-
|
1001
1040
|
/* Uh oh, the app super group isn't in the pool but we don't
|
1002
1041
|
* have the resources to make a new one. The sysadmin should
|
1003
1042
|
* configure the system to let something like this happen
|
1004
1043
|
* as least as possible, but let's try to handle it as well
|
1005
1044
|
* as we can.
|
1006
|
-
*
|
1007
|
-
* First, try to trash an idle process that's the oldest.
|
1008
1045
|
*/
|
1009
|
-
|
1010
|
-
|
1011
|
-
if (process == NULL) {
|
1012
|
-
/* All processes are doing something. We have no choice
|
1013
|
-
* but to trash a non-idle process.
|
1014
|
-
*/
|
1015
|
-
if (options.allowTrashingNonIdleProcesses) {
|
1016
|
-
process = findBestProcessToTrash();
|
1017
|
-
}
|
1018
|
-
} else {
|
1019
|
-
// Check invariant.
|
1020
|
-
assert(process->getGroup()->getWaitlist.empty());
|
1021
|
-
}
|
1022
|
-
if (process == NULL) {
|
1046
|
+
ProcessPtr freedProcess = forceFreeCapacity(NULL, actions);
|
1047
|
+
if (freedProcess == NULL) {
|
1023
1048
|
/* No process is eligible for killing. This could happen if, for example,
|
1024
1049
|
* all (super)groups are currently initializing/restarting/spawning/etc.
|
1025
1050
|
* We have no choice but to satisfy this get() action later when resources
|
@@ -1030,33 +1055,24 @@ public:
|
|
1030
1055
|
options.copyAndPersist().clearLogger(),
|
1031
1056
|
callback));
|
1032
1057
|
} else {
|
1033
|
-
GroupPtr group;
|
1034
|
-
SuperGroupPtr superGroup;
|
1035
|
-
|
1036
|
-
P_DEBUG("Freeing process " << process->inspect());
|
1037
|
-
group = process->getGroup();
|
1038
|
-
assert(group != NULL);
|
1039
|
-
superGroup = group->getSuperGroup();
|
1040
|
-
assert(superGroup != NULL);
|
1041
|
-
|
1042
|
-
group->detach(process, actions);
|
1043
|
-
|
1044
1058
|
/* Now that a process has been trashed we can create
|
1045
1059
|
* the missing SuperGroup.
|
1046
1060
|
*/
|
1047
1061
|
P_DEBUG("Creating new SuperGroup");
|
1062
|
+
SuperGroupPtr superGroup;
|
1048
1063
|
superGroup = boost::make_shared<SuperGroup>(shared_from_this(), options);
|
1049
1064
|
superGroup->initialize();
|
1050
1065
|
superGroups.set(options.getAppGroupName(), superGroup);
|
1051
1066
|
garbageCollectionCond.notify_all();
|
1052
|
-
SessionPtr session = superGroup->get(options, callback
|
1067
|
+
SessionPtr session = superGroup->get(options, callback,
|
1068
|
+
actions);
|
1053
1069
|
/* The SuperGroup is still initializing so the callback
|
1054
1070
|
* should now have been put on the wait list,
|
1055
1071
|
* unless something has changed and we forgot to update
|
1056
1072
|
* some code here...
|
1057
1073
|
*/
|
1058
1074
|
assert(session == NULL);
|
1059
|
-
|
1075
|
+
freedProcess->getGroup()->verifyInvariants();
|
1060
1076
|
superGroup->verifyInvariants();
|
1061
1077
|
}
|
1062
1078
|
|
@@ -1064,17 +1080,19 @@ public:
|
|
1064
1080
|
verifyInvariants();
|
1065
1081
|
verifyExpensiveInvariants();
|
1066
1082
|
P_TRACE(2, "asyncGet() finished");
|
1067
|
-
|
1068
|
-
|
1069
|
-
|
1083
|
+
}
|
1084
|
+
|
1085
|
+
if (!actions.empty()) {
|
1086
|
+
if (lockNow) {
|
1087
|
+
if (lock.owns_lock()) {
|
1070
1088
|
lock.unlock();
|
1071
|
-
runAllActions(actions);
|
1072
|
-
} else {
|
1073
|
-
// This state is not allowed. If we reach
|
1074
|
-
// here then it probably indicates a bug in
|
1075
|
-
// the test suite.
|
1076
|
-
abort();
|
1077
1089
|
}
|
1090
|
+
runAllActions(actions);
|
1091
|
+
} else {
|
1092
|
+
// This state is not allowed. If we reach
|
1093
|
+
// here then it probably indicates a bug in
|
1094
|
+
// the test suite.
|
1095
|
+
abort();
|
1078
1096
|
}
|
1079
1097
|
}
|
1080
1098
|
}
|
@@ -1152,20 +1170,20 @@ public:
|
|
1152
1170
|
garbageCollectionCond.notify_all();
|
1153
1171
|
}
|
1154
1172
|
|
1155
|
-
unsigned int
|
1173
|
+
unsigned int capacityUsed(bool lock = true) const {
|
1156
1174
|
DynamicScopedLock l(syncher, lock);
|
1157
1175
|
SuperGroupMap::const_iterator it, end = superGroups.end();
|
1158
1176
|
int result = 0;
|
1159
1177
|
for (it = superGroups.begin(); it != end; it++) {
|
1160
1178
|
const SuperGroupPtr &superGroup = it->second;
|
1161
|
-
result += superGroup->
|
1179
|
+
result += superGroup->capacityUsed();
|
1162
1180
|
}
|
1163
1181
|
return result;
|
1164
1182
|
}
|
1165
1183
|
|
1166
1184
|
bool atFullCapacity(bool lock = true) const {
|
1167
1185
|
DynamicScopedLock l(syncher, lock);
|
1168
|
-
return
|
1186
|
+
return capacityUsed(false) >= max;
|
1169
1187
|
}
|
1170
1188
|
|
1171
1189
|
vector<ProcessPtr> getProcesses(bool lock = true) const {
|
@@ -1196,7 +1214,8 @@ public:
|
|
1196
1214
|
|
1197
1215
|
/**
|
1198
1216
|
* Returns the total number of processes in the pool, including all disabling and
|
1199
|
-
* disabled processes, but excluding processes that are shutting down
|
1217
|
+
* disabled processes, but excluding processes that are shutting down and excluding
|
1218
|
+
* processes that are being spawned.
|
1200
1219
|
*/
|
1201
1220
|
unsigned int getProcessCount(bool lock = true) const {
|
1202
1221
|
DynamicScopedLock l(syncher, lock);
|
@@ -1385,34 +1404,33 @@ public:
|
|
1385
1404
|
}
|
1386
1405
|
}
|
1387
1406
|
|
1388
|
-
|
1407
|
+
bool restartGroupByName(const StaticString &name, RestartMethod method = RM_DEFAULT) {
|
1389
1408
|
ScopedLock l(syncher);
|
1390
1409
|
SuperGroupMap::iterator sg_it, sg_end = superGroups.end();
|
1391
|
-
unsigned int result = 0;
|
1392
1410
|
|
1393
1411
|
for (sg_it = superGroups.begin(); sg_it != sg_end; sg_it++) {
|
1394
1412
|
const SuperGroupPtr &superGroup = sg_it->second;
|
1395
1413
|
foreach (const GroupPtr &group, superGroup->groups) {
|
1396
|
-
if (
|
1397
|
-
result++;
|
1414
|
+
if (name == group->name) {
|
1398
1415
|
if (!group->restarting()) {
|
1399
|
-
group->restart(group->options);
|
1416
|
+
group->restart(group->options, method);
|
1400
1417
|
}
|
1418
|
+
return true;
|
1401
1419
|
}
|
1402
1420
|
}
|
1403
1421
|
}
|
1404
1422
|
|
1405
|
-
return
|
1423
|
+
return false;
|
1406
1424
|
}
|
1407
1425
|
|
1408
|
-
unsigned int restartSuperGroupsByAppRoot(const
|
1426
|
+
unsigned int restartSuperGroupsByAppRoot(const StaticString &appRoot) {
|
1409
1427
|
ScopedLock l(syncher);
|
1410
1428
|
SuperGroupMap::iterator sg_it, sg_end = superGroups.end();
|
1411
1429
|
unsigned int result = 0;
|
1412
1430
|
|
1413
1431
|
for (sg_it = superGroups.begin(); sg_it != sg_end; sg_it++) {
|
1414
1432
|
const SuperGroupPtr &superGroup = sg_it->second;
|
1415
|
-
if (superGroup->options.appRoot
|
1433
|
+
if (appRoot == superGroup->options.appRoot) {
|
1416
1434
|
result++;
|
1417
1435
|
superGroup->restart(superGroup->options);
|
1418
1436
|
}
|
@@ -1470,7 +1488,13 @@ public:
|
|
1470
1488
|
result << " (restarting...)" << endl;
|
1471
1489
|
}
|
1472
1490
|
if (group->spawning()) {
|
1473
|
-
|
1491
|
+
if (group->processesBeingSpawned == 0) {
|
1492
|
+
result << " (spawning...)" << endl;
|
1493
|
+
} else {
|
1494
|
+
result << " (spawning " << group->processesBeingSpawned << " new " <<
|
1495
|
+
maybePluralize(group->processesBeingSpawned, "process", "processes") <<
|
1496
|
+
"...)" << endl;
|
1497
|
+
}
|
1474
1498
|
}
|
1475
1499
|
result << " Requests in queue: " << group->getWaitlist.size() << endl;
|
1476
1500
|
inspectProcessList(options, result, group, group->enabledProcesses);
|
@@ -1495,7 +1519,7 @@ public:
|
|
1495
1519
|
|
1496
1520
|
result << "<process_count>" << getProcessCount(false) << "</process_count>";
|
1497
1521
|
result << "<max>" << max << "</max>";
|
1498
|
-
result << "<
|
1522
|
+
result << "<capacity_used>" << capacityUsed(false) << "</capacity_used>";
|
1499
1523
|
result << "<get_wait_list_size>" << getWaitlist.size() << "</get_wait_list_size>";
|
1500
1524
|
|
1501
1525
|
if (includeSecrets) {
|
@@ -1519,7 +1543,7 @@ public:
|
|
1519
1543
|
result << "<name>" << escapeForXml(superGroup->name) << "</name>";
|
1520
1544
|
result << "<state>" << superGroup->getStateName() << "</state>";
|
1521
1545
|
result << "<get_wait_list_size>" << superGroup->getWaitlist.size() << "</get_wait_list_size>";
|
1522
|
-
result << "<
|
1546
|
+
result << "<capacity_used>" << superGroup->capacityUsed() << "</capacity_used>";
|
1523
1547
|
if (includeSecrets) {
|
1524
1548
|
result << "<secret>" << escapeForXml(superGroup->secret) << "</secret>";
|
1525
1549
|
}
|