passenger 5.0.0.beta3 → 5.0.0.rc1
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.
- checksums.yaml +8 -8
- checksums.yaml.gz.asc +7 -7
- data.tar.gz.asc +7 -7
- data/.editorconfig +11 -5
- data/CHANGELOG +38 -0
- data/CONTRIBUTING.md +1 -4
- data/Gemfile +0 -1
- data/Gemfile.lock +0 -2
- data/Rakefile +33 -33
- data/bin/passenger +1 -1
- data/bin/passenger-config +1 -1
- data/bin/passenger-install-apache2-module +800 -800
- data/bin/passenger-install-nginx-module +592 -592
- data/bin/passenger-memory-stats +127 -127
- data/bin/passenger-status +216 -216
- data/build/agents.rb +127 -127
- data/build/apache2.rb +87 -87
- data/build/basics.rb +60 -60
- data/build/common_library.rb +165 -165
- data/build/cplusplus_support.rb +51 -51
- data/build/cxx_tests.rb +268 -268
- data/build/debian.rb +143 -143
- data/build/documentation.rb +58 -58
- data/build/integration_tests.rb +81 -81
- data/build/misc.rb +132 -132
- data/build/nginx.rb +20 -20
- data/build/node_tests.rb +7 -7
- data/build/oxt_tests.rb +14 -14
- data/build/packaging.rb +570 -570
- data/build/preprocessor.rb +260 -260
- data/build/rake_extensions.rb +71 -71
- data/build/ruby_extension.rb +29 -29
- data/build/ruby_tests.rb +6 -6
- data/build/test_basics.rb +37 -37
- data/debian.template/control.template +3 -5
- data/dev/copy_boost_headers +134 -134
- data/dev/install_scripts_bootstrap_code.rb +25 -25
- data/dev/list_tests +20 -20
- data/dev/ruby_server.rb +223 -223
- data/dev/runner +18 -18
- data/doc/ServerOptimizationGuide.txt.md +55 -2
- data/doc/Users guide Nginx.txt +0 -26
- data/doc/Users guide Standalone.txt +5 -1
- data/doc/users_guide_snippets/tips.txt +9 -0
- data/ext/common/ApplicationPool2/Group.h +23 -11
- data/ext/common/ApplicationPool2/Implementation.cpp +32 -7
- data/ext/common/ApplicationPool2/Pool.h +22 -17
- data/ext/common/ApplicationPool2/SmartSpawner.h +4 -1
- data/ext/common/ApplicationPool2/Spawner.h +1 -1
- data/ext/common/Constants.h +1 -1
- data/ext/common/agents/Base.cpp +35 -20
- data/ext/common/agents/HelperAgent/Main.cpp +8 -1
- data/ext/common/agents/HelperAgent/OptionParser.h +18 -4
- data/ext/common/agents/HelperAgent/RequestHandler.h +2 -83
- data/ext/common/agents/HelperAgent/RequestHandler/ForwardResponse.cpp +54 -1
- data/ext/common/agents/HelperAgent/RequestHandler/InitRequest.cpp +7 -4
- data/ext/common/agents/Main.cpp +1 -1
- data/ext/common/agents/Watchdog/Main.cpp +54 -19
- data/ext/nginx/Configuration.c +7 -0
- data/ext/nginx/ContentHandler.c +9 -1
- data/helper-scripts/backtrace-sanitizer.rb +106 -87
- data/helper-scripts/crash-watch.rb +32 -0
- data/helper-scripts/download_binaries/extconf.rb +38 -38
- data/helper-scripts/meteor-loader.rb +107 -107
- data/helper-scripts/prespawn +101 -101
- data/helper-scripts/rack-loader.rb +96 -96
- data/helper-scripts/rack-preloader.rb +137 -137
- data/lib/phusion_passenger.rb +292 -292
- data/lib/phusion_passenger/abstract_installer.rb +438 -438
- data/lib/phusion_passenger/active_support3_extensions/init.rb +168 -170
- data/lib/phusion_passenger/admin_tools.rb +20 -20
- data/lib/phusion_passenger/admin_tools/instance.rb +178 -178
- data/lib/phusion_passenger/admin_tools/instance_registry.rb +61 -61
- data/lib/phusion_passenger/admin_tools/memory_stats.rb +267 -267
- data/lib/phusion_passenger/apache2/config_options.rb +182 -182
- data/lib/phusion_passenger/common_library.rb +479 -485
- data/lib/phusion_passenger/config/about_command.rb +161 -161
- data/lib/phusion_passenger/config/admin_command_command.rb +129 -129
- data/lib/phusion_passenger/config/agent_compiler.rb +121 -121
- data/lib/phusion_passenger/config/build_native_support_command.rb +43 -43
- data/lib/phusion_passenger/config/command.rb +25 -25
- data/lib/phusion_passenger/config/compile_agent_command.rb +62 -62
- data/lib/phusion_passenger/config/compile_nginx_engine_command.rb +88 -73
- data/lib/phusion_passenger/config/detach_process_command.rb +72 -72
- data/lib/phusion_passenger/config/download_agent_command.rb +246 -227
- data/lib/phusion_passenger/config/download_nginx_engine_command.rb +245 -224
- data/lib/phusion_passenger/config/install_agent_command.rb +144 -132
- data/lib/phusion_passenger/config/install_standalone_runtime_command.rb +205 -185
- data/lib/phusion_passenger/config/installation_utils.rb +204 -204
- data/lib/phusion_passenger/config/list_instances_command.rb +64 -64
- data/lib/phusion_passenger/config/main.rb +152 -152
- data/lib/phusion_passenger/config/nginx_engine_compiler.rb +319 -300
- data/lib/phusion_passenger/config/reopen_logs_command.rb +67 -67
- data/lib/phusion_passenger/config/restart_app_command.rb +155 -155
- data/lib/phusion_passenger/config/system_metrics_command.rb +13 -13
- data/lib/phusion_passenger/config/utils.rb +95 -95
- data/lib/phusion_passenger/config/validate_install_command.rb +198 -198
- data/lib/phusion_passenger/console_text_template.rb +25 -25
- data/lib/phusion_passenger/constants.rb +90 -90
- data/lib/phusion_passenger/debug_logging.rb +106 -106
- data/lib/phusion_passenger/loader_shared_helpers.rb +447 -432
- data/lib/phusion_passenger/message_channel.rb +312 -312
- data/lib/phusion_passenger/message_client.rb +176 -176
- data/lib/phusion_passenger/native_support.rb +369 -369
- data/lib/phusion_passenger/nginx/config_options.rb +297 -297
- data/lib/phusion_passenger/packaging.rb +131 -131
- data/lib/phusion_passenger/platform_info.rb +360 -360
- data/lib/phusion_passenger/platform_info/apache.rb +767 -767
- data/lib/phusion_passenger/platform_info/apache_detector.rb +199 -199
- data/lib/phusion_passenger/platform_info/binary_compatibility.rb +107 -107
- data/lib/phusion_passenger/platform_info/compiler.rb +570 -570
- data/lib/phusion_passenger/platform_info/curl.rb +32 -32
- data/lib/phusion_passenger/platform_info/cxx_portability.rb +188 -188
- data/lib/phusion_passenger/platform_info/depcheck.rb +372 -372
- data/lib/phusion_passenger/platform_info/depcheck_specs/apache2.rb +109 -109
- data/lib/phusion_passenger/platform_info/depcheck_specs/compiler_toolchain.rb +4 -4
- data/lib/phusion_passenger/platform_info/depcheck_specs/gems.rb +10 -34
- data/lib/phusion_passenger/platform_info/depcheck_specs/libs.rb +101 -101
- data/lib/phusion_passenger/platform_info/depcheck_specs/ruby.rb +5 -5
- data/lib/phusion_passenger/platform_info/depcheck_specs/utilities.rb +13 -13
- data/lib/phusion_passenger/platform_info/linux.rb +55 -55
- data/lib/phusion_passenger/platform_info/operating_system.rb +149 -149
- data/lib/phusion_passenger/platform_info/ruby.rb +468 -448
- data/lib/phusion_passenger/platform_info/zlib.rb +9 -9
- data/lib/phusion_passenger/plugin.rb +66 -66
- data/lib/phusion_passenger/preloader_shared_helpers.rb +126 -126
- data/lib/phusion_passenger/public_api.rb +191 -191
- data/lib/phusion_passenger/rack/out_of_band_gc.rb +93 -94
- data/lib/phusion_passenger/rack/thread_handler_extension.rb +231 -227
- data/lib/phusion_passenger/request_handler.rb +567 -577
- data/lib/phusion_passenger/request_handler/thread_handler.rb +379 -381
- data/lib/phusion_passenger/ruby_core_enhancements.rb +86 -86
- data/lib/phusion_passenger/ruby_core_io_enhancements.rb +74 -74
- data/lib/phusion_passenger/simple_benchmarking.rb +25 -25
- data/lib/phusion_passenger/standalone/app_finder.rb +153 -150
- data/lib/phusion_passenger/standalone/command.rb +44 -40
- data/lib/phusion_passenger/standalone/config_utils.rb +53 -53
- data/lib/phusion_passenger/standalone/control_utils.rb +38 -59
- data/lib/phusion_passenger/standalone/main.rb +73 -73
- data/lib/phusion_passenger/standalone/start_command.rb +697 -685
- data/lib/phusion_passenger/standalone/start_command/builtin_engine.rb +193 -155
- data/lib/phusion_passenger/standalone/start_command/nginx_engine.rb +162 -133
- data/lib/phusion_passenger/standalone/status_command.rb +64 -64
- data/lib/phusion_passenger/standalone/stop_command.rb +72 -72
- data/lib/phusion_passenger/standalone/version_command.rb +9 -9
- data/lib/phusion_passenger/union_station/connection.rb +32 -32
- data/lib/phusion_passenger/union_station/core.rb +251 -251
- data/lib/phusion_passenger/union_station/transaction.rb +126 -126
- data/lib/phusion_passenger/utils.rb +199 -167
- data/lib/phusion_passenger/utils/ansi_colors.rb +128 -128
- data/lib/phusion_passenger/utils/download.rb +196 -196
- data/lib/phusion_passenger/utils/file_system_watcher.rb +158 -158
- data/lib/phusion_passenger/utils/hosts_file_parser.rb +101 -101
- data/lib/phusion_passenger/utils/lock.rb +31 -31
- data/lib/phusion_passenger/utils/native_support_utils.rb +31 -31
- data/lib/phusion_passenger/utils/progress_bar.rb +26 -26
- data/lib/phusion_passenger/utils/shellwords.rb +20 -20
- data/lib/phusion_passenger/utils/terminal_choice_menu.rb +206 -206
- data/lib/phusion_passenger/utils/unseekable_socket.rb +272 -272
- data/lib/phusion_passenger/vendor/crash_watch/app.rb +129 -0
- data/lib/phusion_passenger/vendor/crash_watch/gdb_controller.rb +341 -0
- data/lib/phusion_passenger/vendor/crash_watch/version.rb +24 -0
- data/lib/phusion_passenger/vendor/daemon_controller.rb +877 -0
- data/lib/phusion_passenger/vendor/daemon_controller/lock_file.rb +127 -0
- data/lib/phusion_passenger/vendor/daemon_controller/spawn.rb +26 -0
- data/lib/phusion_passenger/vendor/daemon_controller/version.rb +29 -0
- data/packaging/rpm/passenger_spec/passenger.spec.template +0 -1
- data/passenger.gemspec +0 -1
- data/resources/templates/config/nginx_engine_compiler/possible_solutions_for_download_and_extraction_problems.txt.erb +27 -0
- data/resources/templates/standalone/config.erb +19 -15
- data/test/integration_tests/apache2_tests.rb +566 -566
- data/test/integration_tests/downloaded_binaries_tests.rb +126 -125
- data/test/integration_tests/native_packaging_spec.rb +296 -296
- data/test/integration_tests/nginx_tests.rb +393 -393
- data/test/integration_tests/shared/example_webapp_tests.rb +282 -280
- data/test/integration_tests/source_packaging_test.rb +138 -138
- data/test/integration_tests/spec_helper.rb +5 -5
- data/test/integration_tests/standalone_tests.rb +367 -367
- data/test/ruby/debug_logging_spec.rb +133 -133
- data/test/ruby/message_channel_spec.rb +186 -186
- data/test/ruby/rack/loader_spec.rb +28 -28
- data/test/ruby/rack/preloader_spec.rb +34 -34
- data/test/ruby/rails3.0/loader_spec.rb +12 -12
- data/test/ruby/rails3.0/preloader_spec.rb +18 -18
- data/test/ruby/rails3.1/loader_spec.rb +12 -12
- data/test/ruby/rails3.1/preloader_spec.rb +18 -18
- data/test/ruby/rails3.2/loader_spec.rb +12 -12
- data/test/ruby/rails3.2/preloader_spec.rb +18 -18
- data/test/ruby/rails4.0/loader_spec.rb +12 -12
- data/test/ruby/rails4.0/preloader_spec.rb +18 -18
- data/test/ruby/rails4.1/loader_spec.rb +12 -12
- data/test/ruby/rails4.1/preloader_spec.rb +18 -18
- data/test/ruby/request_handler_spec.rb +730 -730
- data/test/ruby/shared/loader_sharedspec.rb +224 -224
- data/test/ruby/shared/rails/union_station_extensions_sharedspec.rb +327 -327
- data/test/ruby/shared/ruby_loader_sharedspec.rb +47 -47
- data/test/ruby/spec_helper.rb +65 -65
- data/test/ruby/standalone/runtime_installer_spec.rb +384 -384
- data/test/ruby/union_station_spec.rb +276 -276
- data/test/ruby/utils/file_system_watcher_spec.rb +220 -220
- data/test/ruby/utils/hosts_file_parser.rb +248 -248
- data/test/ruby/utils/tee_input_spec.rb +215 -215
- data/test/ruby/utils/unseekable_socket_spec.rb +57 -57
- data/test/ruby/utils_spec.rb +21 -21
- data/test/stub/rack/config.ru +87 -87
- data/test/stub/rack/library.rb +8 -8
- data/test/stub/rack/start.rb +30 -30
- data/test/support/apache2_controller.rb +191 -191
- data/test/support/nginx_controller.rb +90 -99
- data/test/support/placebo-preloader.rb +57 -57
- data/test/support/test_helper.rb +435 -435
- metadata +11 -21
- metadata.gz.asc +7 -7
- data/lib/phusion_passenger/standalone/command2.rb +0 -292
- data/lib/phusion_passenger/standalone/start2_command.rb +0 -799
- data/resources/templates/standalone/download_tool_missing.txt.erb +0 -18
- data/resources/templates/standalone/possible_solutions_for_download_and_extraction_problems.txt.erb +0 -17
- data/resources/templates/standalone/run_installer_as_root.txt.erb +0 -8
@@ -29,76 +29,76 @@ PhusionPassenger.require_passenger_lib 'standalone/control_utils'
|
|
29
29
|
PhusionPassenger.require_passenger_lib 'ruby_core_enhancements'
|
30
30
|
|
31
31
|
module PhusionPassenger
|
32
|
-
module Standalone
|
32
|
+
module Standalone
|
33
33
|
|
34
|
-
class StatusCommand < Command
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
34
|
+
class StatusCommand < Command
|
35
|
+
def run
|
36
|
+
@options = { :port => 3000 }
|
37
|
+
parse_options
|
38
|
+
find_pid_file
|
39
|
+
create_controller
|
40
|
+
begin
|
41
|
+
running = @controller.running?
|
42
|
+
pid = @controller.pid
|
43
|
+
rescue SystemCallError, IOError
|
44
|
+
running = false
|
45
|
+
end
|
46
|
+
if running
|
47
|
+
puts "#{PROGRAM_NAME} Standalone is running on PID #{pid}, according to PID file #{@options[:pid_file]}"
|
48
|
+
else
|
49
|
+
puts "#{PROGRAM_NAME} Standalone is not running, according to PID file #{@options[:pid_file]}"
|
50
|
+
end
|
51
|
+
end
|
52
52
|
|
53
|
-
private
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
53
|
+
private
|
54
|
+
def self.create_option_parser(options)
|
55
|
+
OptionParser.new do |opts|
|
56
|
+
nl = "\n" + ' ' * 37
|
57
|
+
opts.banner = "Usage: passenger status [OPTIONS]\n"
|
58
|
+
opts.separator "Shows the status of a running #{PROGRAM_NAME} Standalone instance."
|
59
|
+
opts.separator ""
|
60
60
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
61
|
+
opts.separator "Options:"
|
62
|
+
opts.on("-p", "--port NUMBER", Integer,
|
63
|
+
"The port number of the #{PROGRAM_NAME}#{nl}" +
|
64
|
+
"instance. Default: 3000") do |value|
|
65
|
+
options[:port] = value
|
66
|
+
end
|
67
|
+
opts.on("--pid-file FILE", String,
|
68
|
+
"PID file of the running #{PROGRAM_NAME}#{nl}" +
|
69
|
+
"Standalone instance") do |value|
|
70
|
+
options[:pid_file] = value
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
74
|
|
75
|
-
|
76
|
-
|
75
|
+
def find_pid_file
|
76
|
+
return if @options[:pid_file]
|
77
77
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
78
|
+
["tmp/pids", "."].each do |dir|
|
79
|
+
path = File.absolute_path_no_resolve("#{dir}/passenger.#{@options[:port]}.pid")
|
80
|
+
if File.exist?(path)
|
81
|
+
@options[:pid_file] = path
|
82
|
+
return
|
83
|
+
end
|
84
|
+
end
|
85
85
|
|
86
|
-
|
87
|
-
|
88
|
-
|
86
|
+
Standalone::ControlUtils.warn_pid_file_not_found(@options)
|
87
|
+
exit 1
|
88
|
+
end
|
89
89
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
end
|
90
|
+
def create_controller
|
91
|
+
Standalone::ControlUtils.require_daemon_controller
|
92
|
+
@controller = DaemonController.new(
|
93
|
+
:identifier => "#{PROGRAM_NAME} Standalone engine",
|
94
|
+
:start_command => "true", # Doesn't matter
|
95
|
+
:ping_command => "true", # Doesn't matter
|
96
|
+
:pid_file => @options[:pid_file],
|
97
|
+
:log_file => "/dev/null",
|
98
|
+
:timeout => 25
|
99
|
+
)
|
100
|
+
end
|
101
|
+
end
|
102
102
|
|
103
|
-
end
|
103
|
+
end
|
104
104
|
end
|
@@ -29,84 +29,84 @@ PhusionPassenger.require_passenger_lib 'standalone/control_utils'
|
|
29
29
|
PhusionPassenger.require_passenger_lib 'ruby_core_enhancements'
|
30
30
|
|
31
31
|
module PhusionPassenger
|
32
|
-
module Standalone
|
32
|
+
module Standalone
|
33
33
|
|
34
|
-
class StopCommand < Command
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
34
|
+
class StopCommand < Command
|
35
|
+
def run
|
36
|
+
@options = { :port => 3000 }
|
37
|
+
parse_options
|
38
|
+
find_pid_file
|
39
|
+
create_controller
|
40
|
+
begin
|
41
|
+
running = @controller.running?
|
42
|
+
rescue SystemCallError, IOError
|
43
|
+
running = false
|
44
|
+
end
|
45
|
+
if running
|
46
|
+
@controller.stop
|
47
|
+
else
|
48
|
+
Standalone::ControlUtils.warn_pid_file_not_found(@options)
|
49
|
+
exit 1
|
50
|
+
end
|
51
|
+
end
|
52
52
|
|
53
|
-
private
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
53
|
+
private
|
54
|
+
def self.create_option_parser(options)
|
55
|
+
OptionParser.new do |opts|
|
56
|
+
nl = "\n" + ' ' * 37
|
57
|
+
opts.banner = "Usage: passenger stop [OPTIONS]\n"
|
58
|
+
opts.separator "Stops a running #{PROGRAM_NAME} Standalone instance."
|
59
|
+
opts.separator ""
|
60
60
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
61
|
+
opts.separator "Options:"
|
62
|
+
opts.on("-p", "--port NUMBER", Integer,
|
63
|
+
"The port number of the #{PROGRAM_NAME}#{nl}" +
|
64
|
+
"instance. Default: 3000") do |value|
|
65
|
+
options[:port] = value
|
66
|
+
end
|
67
|
+
opts.on("--pid-file FILE", String,
|
68
|
+
"PID file of the running #{PROGRAM_NAME}#{nl}" +
|
69
|
+
"Standalone instance") do |value|
|
70
|
+
options[:pid_file] = value
|
71
|
+
end
|
72
|
+
opts.on("--ignore-pid-not-found", "-i",
|
73
|
+
"Don't abort with an error if PID file cannot be found") do
|
74
|
+
options[:ignore_pid_not_found] = true
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
78
|
|
79
|
-
|
80
|
-
|
79
|
+
def find_pid_file
|
80
|
+
return if @options[:pid_file]
|
81
81
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
82
|
+
["tmp/pids", "."].each do |dir|
|
83
|
+
path = File.absolute_path_no_resolve("#{dir}/passenger.#{@options[:port]}.pid")
|
84
|
+
if File.exist?(path)
|
85
|
+
@options[:pid_file] = path
|
86
|
+
return
|
87
|
+
end
|
88
|
+
end
|
89
89
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
90
|
+
if @options[:ignore_pid_not_found]
|
91
|
+
exit
|
92
|
+
else
|
93
|
+
Standalone::ControlUtils.warn_pid_file_not_found(@options)
|
94
|
+
exit 1
|
95
|
+
end
|
96
|
+
end
|
97
97
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
end
|
98
|
+
def create_controller
|
99
|
+
Standalone::ControlUtils.require_daemon_controller
|
100
|
+
@controller = DaemonController.new(
|
101
|
+
:identifier => "#{PROGRAM_NAME} Standalone engine",
|
102
|
+
:start_command => "true", # Doesn't matter
|
103
|
+
:ping_command => "true", # Doesn't matter
|
104
|
+
:pid_file => @options[:pid_file],
|
105
|
+
:log_file => "/dev/null",
|
106
|
+
:timeout => 25
|
107
|
+
)
|
108
|
+
end
|
109
|
+
end
|
110
110
|
|
111
|
-
end
|
111
|
+
end
|
112
112
|
end
|
@@ -23,15 +23,15 @@
|
|
23
23
|
PhusionPassenger.require_passenger_lib 'standalone/command'
|
24
24
|
|
25
25
|
module PhusionPassenger
|
26
|
-
module Standalone
|
26
|
+
module Standalone
|
27
27
|
|
28
|
-
class VersionCommand < Command
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
end
|
28
|
+
class VersionCommand < Command
|
29
|
+
def run
|
30
|
+
puts "Phusion Passenger version #{VERSION_STRING}"
|
31
|
+
puts
|
32
|
+
puts '"Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.'
|
33
|
+
end
|
34
|
+
end
|
35
35
|
|
36
|
-
end
|
36
|
+
end
|
37
37
|
end
|
@@ -24,44 +24,44 @@
|
|
24
24
|
PhusionPassenger.require_passenger_lib 'message_channel'
|
25
25
|
|
26
26
|
module PhusionPassenger
|
27
|
-
module UnionStation
|
27
|
+
module UnionStation
|
28
28
|
|
29
|
-
class Connection
|
30
|
-
|
31
|
-
|
29
|
+
class Connection
|
30
|
+
attr_reader :mutex
|
31
|
+
attr_accessor :channel
|
32
32
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
33
|
+
def initialize(io)
|
34
|
+
@mutex = Mutex.new
|
35
|
+
@refcount = 1
|
36
|
+
@channel = MessageChannel.new(io) if io
|
37
|
+
end
|
38
38
|
|
39
|
-
|
40
|
-
|
41
|
-
|
39
|
+
def connected?
|
40
|
+
return !!@channel
|
41
|
+
end
|
42
42
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
43
|
+
def disconnect
|
44
|
+
@channel.close if @channel
|
45
|
+
@channel = nil
|
46
|
+
end
|
47
47
|
|
48
|
-
|
49
|
-
|
50
|
-
|
48
|
+
def ref
|
49
|
+
@refcount += 1
|
50
|
+
end
|
51
51
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
52
|
+
def unref
|
53
|
+
@refcount -= 1
|
54
|
+
if @refcount == 0
|
55
|
+
disconnect
|
56
|
+
end
|
57
|
+
end
|
58
58
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
end
|
59
|
+
def synchronize
|
60
|
+
@mutex.synchronize do
|
61
|
+
yield
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
65
|
|
66
|
-
end # module UnionStation
|
66
|
+
end # module UnionStation
|
67
67
|
end # module PhusionPassenger
|
@@ -29,255 +29,255 @@ PhusionPassenger.require_passenger_lib 'utils/lock'
|
|
29
29
|
PhusionPassenger.require_passenger_lib 'debug_logging'
|
30
30
|
|
31
31
|
module PhusionPassenger
|
32
|
-
module UnionStation
|
33
|
-
|
34
|
-
class Core
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
private
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
end
|
281
|
-
|
282
|
-
end # module UnionStation
|
32
|
+
module UnionStation
|
33
|
+
|
34
|
+
class Core
|
35
|
+
RETRY_SLEEP = 0.2
|
36
|
+
NETWORK_ERRORS = [Errno::EPIPE, Errno::ECONNREFUSED, Errno::ECONNRESET,
|
37
|
+
Errno::EHOSTUNREACH, Errno::ENETDOWN, Errno::ENETUNREACH, Errno::ETIMEDOUT]
|
38
|
+
|
39
|
+
include Utils
|
40
|
+
include DebugLogging
|
41
|
+
|
42
|
+
def self.new_from_options(options)
|
43
|
+
if options["analytics"] && options["logging_agent_address"]
|
44
|
+
return new(options["logging_agent_address"],
|
45
|
+
options["logging_agent_username"],
|
46
|
+
options["logging_agent_password"],
|
47
|
+
options["node_name"])
|
48
|
+
else
|
49
|
+
return nil
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
attr_accessor :max_connect_tries
|
54
|
+
attr_accessor :reconnect_timeout
|
55
|
+
|
56
|
+
def initialize(logging_agent_address, username, password, node_name)
|
57
|
+
@server_address = logging_agent_address
|
58
|
+
@username = username
|
59
|
+
@password = password
|
60
|
+
if node_name && !node_name.empty?
|
61
|
+
@node_name = node_name
|
62
|
+
else
|
63
|
+
@node_name = `hostname`.strip
|
64
|
+
end
|
65
|
+
@random_dev = File.open("/dev/urandom")
|
66
|
+
|
67
|
+
# This mutex protects the following instance variables, but
|
68
|
+
# not the contents of @connection.
|
69
|
+
@mutex = Mutex.new
|
70
|
+
|
71
|
+
@connection = Connection.new(nil)
|
72
|
+
if @server_address && local_socket_address?(@server_address)
|
73
|
+
@max_connect_tries = 10
|
74
|
+
else
|
75
|
+
@max_connect_tries = 1
|
76
|
+
end
|
77
|
+
@reconnect_timeout = 1
|
78
|
+
@next_reconnect_time = Time.utc(1980, 1, 1)
|
79
|
+
end
|
80
|
+
|
81
|
+
def clear_connection
|
82
|
+
@mutex.synchronize do
|
83
|
+
@connection.synchronize do
|
84
|
+
@random_dev = File.open("/dev/urandom") if @random_dev.closed?
|
85
|
+
@connection.unref
|
86
|
+
@connection = Connection.new(nil)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def close
|
92
|
+
@mutex.synchronize do
|
93
|
+
@connection.synchronize do
|
94
|
+
@random_dev.close
|
95
|
+
@connection.unref
|
96
|
+
@connection = nil
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def new_transaction(group_name, category = :requests, union_station_key = "-")
|
102
|
+
if !@server_address
|
103
|
+
return Transaction.new
|
104
|
+
elsif !group_name || group_name.empty?
|
105
|
+
raise ArgumentError, "Group name may not be empty"
|
106
|
+
end
|
107
|
+
|
108
|
+
txn_id = (Core.current_time.to_i / 60).to_s(36)
|
109
|
+
txn_id << "-#{random_token(11)}"
|
110
|
+
|
111
|
+
Utils::Lock.new(@mutex).synchronize do |lock|
|
112
|
+
if current_time < @next_reconnect_time
|
113
|
+
return Transaction.new
|
114
|
+
end
|
115
|
+
|
116
|
+
Utils::Lock.new(@connection.mutex).synchronize do |connection_lock|
|
117
|
+
if !@connection.connected?
|
118
|
+
begin
|
119
|
+
connect
|
120
|
+
connection_lock.reset(@connection.mutex)
|
121
|
+
rescue SystemCallError, IOError
|
122
|
+
@connection.disconnect
|
123
|
+
warn("Cannot connect to the logging agent at #{@server_address}; " +
|
124
|
+
"retrying in #{@reconnect_timeout} second(s).")
|
125
|
+
@next_reconnect_time = current_time + @reconnect_timeout
|
126
|
+
return Transaction.new
|
127
|
+
rescue Exception => e
|
128
|
+
@connection.disconnect
|
129
|
+
raise e
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
begin
|
134
|
+
@connection.channel.write("openTransaction",
|
135
|
+
txn_id, group_name, "", category,
|
136
|
+
Core.timestamp_string,
|
137
|
+
union_station_key,
|
138
|
+
true,
|
139
|
+
true)
|
140
|
+
result = @connection.channel.read
|
141
|
+
if result != ["ok"]
|
142
|
+
raise "Expected logging server to respond with 'ok', but got #{result.inspect} instead"
|
143
|
+
end
|
144
|
+
return Transaction.new(@connection, txn_id)
|
145
|
+
rescue SystemCallError, IOError
|
146
|
+
@connection.disconnect
|
147
|
+
warn("The logging agent at #{@server_address}" <<
|
148
|
+
" closed the connection; will reconnect in " <<
|
149
|
+
"#{@reconnect_timeout} second(s).")
|
150
|
+
@next_reconnect_time = current_time + @reconnect_timeout
|
151
|
+
return Transaction.new
|
152
|
+
rescue Exception => e
|
153
|
+
@connection.disconnect
|
154
|
+
raise e
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def continue_transaction(txn_id, group_name, category = :requests, union_station_key = "-")
|
161
|
+
if !@server_address
|
162
|
+
return Transaction.new
|
163
|
+
elsif !txn_id || txn_id.empty?
|
164
|
+
raise ArgumentError, "Transaction ID may not be empty"
|
165
|
+
end
|
166
|
+
|
167
|
+
Utils::Lock.new(@mutex).synchronize do |lock|
|
168
|
+
if current_time < @next_reconnect_time
|
169
|
+
return Transaction.new
|
170
|
+
end
|
171
|
+
|
172
|
+
Utils::Lock.new(@connection.mutex).synchronize do |connection_lock|
|
173
|
+
if !@connection.connected?
|
174
|
+
begin
|
175
|
+
connect
|
176
|
+
connection_lock.reset(@connection.mutex)
|
177
|
+
rescue SystemCallError, IOError
|
178
|
+
@connection.disconnect
|
179
|
+
warn("Cannot connect to the logging agent at #{@server_address}; " +
|
180
|
+
"retrying in #{@reconnect_timeout} second(s).")
|
181
|
+
@next_reconnect_time = current_time + @reconnect_timeout
|
182
|
+
return Transaction.new
|
183
|
+
rescue Exception => e
|
184
|
+
@connection.disconnect
|
185
|
+
raise e
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
begin
|
190
|
+
@connection.channel.write("openTransaction",
|
191
|
+
txn_id, group_name, "", category,
|
192
|
+
Core.timestamp_string,
|
193
|
+
union_station_key,
|
194
|
+
true)
|
195
|
+
return Transaction.new(@connection, txn_id)
|
196
|
+
rescue SystemCallError, IOError
|
197
|
+
@connection.disconnect
|
198
|
+
warn("The logging agent at #{@server_address}" <<
|
199
|
+
" closed the connection; will reconnect in " <<
|
200
|
+
"#{@reconnect_timeout} second(s).")
|
201
|
+
@next_reconnect_time = current_time + @reconnect_timeout
|
202
|
+
return Transaction.new
|
203
|
+
rescue Exception => e
|
204
|
+
@connection.disconnect
|
205
|
+
raise e
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
private
|
212
|
+
RANDOM_CHARS = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
|
213
|
+
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
214
|
+
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
|
215
|
+
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
216
|
+
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
|
217
|
+
|
218
|
+
def connect
|
219
|
+
socket = connect_to_server(@server_address)
|
220
|
+
channel = MessageChannel.new(socket)
|
221
|
+
|
222
|
+
result = channel.read
|
223
|
+
if result.nil?
|
224
|
+
raise EOFError
|
225
|
+
elsif result.size != 2 || result[0] != "version"
|
226
|
+
raise IOError, "The logging agent didn't sent a valid version identifier"
|
227
|
+
elsif result[1] != "1"
|
228
|
+
raise IOError, "Unsupported logging agent protocol version #{result[1]}"
|
229
|
+
end
|
230
|
+
|
231
|
+
channel.write_scalar(@username)
|
232
|
+
channel.write_scalar(@password)
|
233
|
+
|
234
|
+
result = channel.read
|
235
|
+
if result.nil?
|
236
|
+
raise EOFError
|
237
|
+
elsif result[0] != "ok"
|
238
|
+
raise SecurityError, result[0]
|
239
|
+
end
|
240
|
+
|
241
|
+
channel.write("init", @node_name)
|
242
|
+
args = channel.read
|
243
|
+
if !args
|
244
|
+
raise Errno::ECONNREFUSED, "Cannot connect to logging agent"
|
245
|
+
elsif args.size != 1
|
246
|
+
raise IOError, "Logging agent returned an invalid reply for the 'init' command"
|
247
|
+
elsif args[0] == "server shutting down"
|
248
|
+
raise Errno::ECONNREFUSED, "Cannot connect to logging agent"
|
249
|
+
elsif args[0] != "ok"
|
250
|
+
raise IOError, "Logging agent returned an invalid reply for the 'init' command"
|
251
|
+
end
|
252
|
+
|
253
|
+
@connection.unref
|
254
|
+
@connection = Connection.new(socket)
|
255
|
+
rescue Exception => e
|
256
|
+
socket.close if socket && !socket.closed?
|
257
|
+
raise e
|
258
|
+
end
|
259
|
+
|
260
|
+
def random_token(length)
|
261
|
+
token = ""
|
262
|
+
@random_dev.read(length).each_byte do |c|
|
263
|
+
token << RANDOM_CHARS[c % RANDOM_CHARS.size]
|
264
|
+
end
|
265
|
+
return token
|
266
|
+
end
|
267
|
+
|
268
|
+
def current_time
|
269
|
+
return self.class.current_time
|
270
|
+
end
|
271
|
+
|
272
|
+
def self.current_time
|
273
|
+
return Time.now
|
274
|
+
end
|
275
|
+
|
276
|
+
def self.timestamp_string(time = current_time)
|
277
|
+
timestamp = time.to_i * 1_000_000 + time.usec
|
278
|
+
return timestamp.to_s(36)
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
end # module UnionStation
|
283
283
|
end # module PhusionPassenger
|