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
@@ -26,143 +26,143 @@ PhusionPassenger.require_passenger_lib 'union_station/core'
|
|
26
26
|
PhusionPassenger.require_passenger_lib 'utils/native_support_utils'
|
27
27
|
|
28
28
|
module PhusionPassenger
|
29
|
-
module UnionStation
|
29
|
+
module UnionStation
|
30
30
|
|
31
|
-
class Transaction
|
32
|
-
|
31
|
+
class Transaction
|
32
|
+
include DebugLogging
|
33
33
|
|
34
|
-
|
34
|
+
attr_reader :txn_id
|
35
35
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
36
|
+
def initialize(connection = nil, txn_id = nil)
|
37
|
+
if connection
|
38
|
+
@connection = connection
|
39
|
+
@txn_id = txn_id
|
40
|
+
connection.ref
|
41
|
+
end
|
42
|
+
end
|
43
43
|
|
44
|
-
|
45
|
-
|
46
|
-
|
44
|
+
def null?
|
45
|
+
return !@connection || !@connection.connected?
|
46
|
+
end
|
47
47
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
48
|
+
def message(text)
|
49
|
+
if !@connection
|
50
|
+
timestamp_string = Core.timestamp_string
|
51
|
+
trace(3, "[Union Station log to null] #{@txn_id} #{timestamp_string} #{text}")
|
52
|
+
return
|
53
|
+
end
|
54
|
+
@connection.synchronize do
|
55
|
+
return if !@connection.connected?
|
56
|
+
begin
|
57
|
+
timestamp_string = Core.timestamp_string
|
58
|
+
trace(3, "[Union Station log] #{@txn_id} #{timestamp_string} #{text}")
|
59
|
+
@connection.channel.write("log", @txn_id, timestamp_string)
|
60
|
+
@connection.channel.write_scalar(text)
|
61
|
+
rescue SystemCallError, IOError => e
|
62
|
+
@connection.disconnect
|
63
|
+
warn("Error communicating with the logging agent: #{e.message}")
|
64
|
+
rescue Exception => e
|
65
|
+
@connection.disconnect
|
66
|
+
raise e
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
70
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
71
|
+
def begin_measure(name, extra_info = nil)
|
72
|
+
if extra_info
|
73
|
+
extra_info_base64 = [extra_info].pack("m")
|
74
|
+
extra_info_base64.gsub!("\n", "")
|
75
|
+
extra_info_base64.strip!
|
76
|
+
else
|
77
|
+
extra_info_base64 = nil
|
78
|
+
end
|
79
|
+
times = Utils::NativeSupportUtils.process_times
|
80
|
+
message "BEGIN: #{name} (#{current_timestamp.to_s(36)},#{times.utime.to_s(36)},#{times.stime.to_s(36)}) #{extra_info_base64}"
|
81
|
+
end
|
82
82
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
83
|
+
def end_measure(name, error_encountered = false)
|
84
|
+
times = Utils::NativeSupportUtils.process_times
|
85
|
+
if error_encountered
|
86
|
+
message "FAIL: #{name} (#{current_timestamp.to_s(36)},#{times.utime.to_s(36)},#{times.stime.to_s(36)})"
|
87
|
+
else
|
88
|
+
message "END: #{name} (#{current_timestamp.to_s(36)},#{times.utime.to_s(36)},#{times.stime.to_s(36)})"
|
89
|
+
end
|
90
|
+
end
|
91
91
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
92
|
+
def measure(name, extra_info = nil)
|
93
|
+
begin_measure(name, extra_info)
|
94
|
+
begin
|
95
|
+
yield
|
96
|
+
rescue Exception
|
97
|
+
error = true
|
98
|
+
is_closed = closed?
|
99
|
+
raise
|
100
|
+
ensure
|
101
|
+
end_measure(name, error) if !is_closed
|
102
|
+
end
|
103
|
+
end
|
104
104
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
105
|
+
def measured_time_points(name, begin_time, end_time, extra_info = nil)
|
106
|
+
if extra_info
|
107
|
+
extra_info_base64 = [extra_info].pack("m")
|
108
|
+
extra_info_base64.gsub!("\n", "")
|
109
|
+
extra_info_base64.strip!
|
110
|
+
else
|
111
|
+
extra_info_base64 = nil
|
112
|
+
end
|
113
|
+
begin_timestamp = begin_time.to_i * 1_000_000 + begin_time.usec
|
114
|
+
end_timestamp = end_time.to_i * 1_000_000 + end_time.usec
|
115
|
+
message "BEGIN: #{name} (#{begin_timestamp.to_s(36)}) #{extra_info_base64}"
|
116
|
+
message "END: #{name} (#{end_timestamp.to_s(36)})"
|
117
|
+
end
|
118
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
|
-
|
119
|
+
def close(flush_to_disk = false)
|
120
|
+
@connection.synchronize do
|
121
|
+
return if !@connection.connected?
|
122
|
+
begin
|
123
|
+
# We need an ACK here. See thread_handler.rb finalize_request.
|
124
|
+
@connection.channel.write("closeTransaction", @txn_id,
|
125
|
+
Core.timestamp_string, true)
|
126
|
+
result = @connection.channel.read
|
127
|
+
if result != ["ok"]
|
128
|
+
raise "Expected logging agent to respond with 'ok', but got #{result.inspect} instead"
|
129
|
+
end
|
130
|
+
if flush_to_disk
|
131
|
+
@connection.channel.write("flush")
|
132
|
+
result = @connection.channel.read
|
133
|
+
if result != ["ok"]
|
134
|
+
raise "Invalid logging agent response #{result.inspect} to the 'flush' command"
|
135
|
+
end
|
136
|
+
end
|
137
|
+
rescue SystemCallError, IOError => e
|
138
|
+
@connection.disconnect
|
139
|
+
warn("Error communicating with the logging agent: #{e.message}")
|
140
|
+
rescue Exception => e
|
141
|
+
@connection.disconnect
|
142
|
+
raise e
|
143
|
+
ensure
|
144
|
+
@connection.unref
|
145
|
+
@connection = nil
|
146
|
+
end
|
147
|
+
end if @connection
|
148
|
+
end
|
149
149
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
150
|
+
def closed?
|
151
|
+
if @connection
|
152
|
+
@connection.synchronize do
|
153
|
+
return !@connection.connected?
|
154
|
+
end
|
155
|
+
else
|
156
|
+
return nil
|
157
|
+
end
|
158
|
+
end
|
159
159
|
|
160
|
-
private
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
end
|
160
|
+
private
|
161
|
+
def current_timestamp
|
162
|
+
time = Core.current_time
|
163
|
+
return time.to_i * 1_000_000 + time.usec
|
164
|
+
end
|
165
|
+
end
|
166
166
|
|
167
|
-
end # module UnionStation
|
167
|
+
end # module UnionStation
|
168
168
|
end # module PhusionPassenger
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# encoding: binary
|
2
2
|
# Phusion Passenger - https://www.phusionpassenger.com/
|
3
|
-
# Copyright (c) 2010-
|
3
|
+
# Copyright (c) 2010-2015 Phusion
|
4
4
|
#
|
5
5
|
# "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
|
6
6
|
#
|
@@ -24,171 +24,203 @@
|
|
24
24
|
|
25
25
|
module PhusionPassenger
|
26
26
|
|
27
|
-
# Utility functions.
|
28
|
-
module Utils
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
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
|
-
end
|
27
|
+
# Utility functions.
|
28
|
+
module Utils
|
29
|
+
extend self # Make methods available as class methods.
|
30
|
+
|
31
|
+
def self.included(klass)
|
32
|
+
# When included into another class, make sure that Utils
|
33
|
+
# methods are made private.
|
34
|
+
public_instance_methods(false).each do |method_name|
|
35
|
+
klass.send(:private, method_name)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Generate a long, cryptographically secure random ID string, which
|
40
|
+
# is also a valid filename.
|
41
|
+
def generate_random_id(method)
|
42
|
+
data = File.open("/dev/urandom", "rb") do |f|
|
43
|
+
f.read(64)
|
44
|
+
end
|
45
|
+
case method
|
46
|
+
when :base64
|
47
|
+
data = [data].pack('m')
|
48
|
+
data.gsub!("\n", '')
|
49
|
+
data.gsub!("+", '')
|
50
|
+
data.gsub!("/", '')
|
51
|
+
data.gsub!(/==$/, '')
|
52
|
+
return data
|
53
|
+
when :hex
|
54
|
+
return data.unpack('H*')[0]
|
55
|
+
else
|
56
|
+
raise ArgumentError, "Invalid method #{method.inspect}"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def retry_at_most(n, *exceptions)
|
61
|
+
n.times do |i|
|
62
|
+
begin
|
63
|
+
return yield
|
64
|
+
rescue *exceptions
|
65
|
+
if i == n - 1
|
66
|
+
raise
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# Print the given exception, including the stack trace, to STDERR.
|
73
|
+
#
|
74
|
+
# +current_location+ is a string which describes where the code is
|
75
|
+
# currently at. Usually the current class name will be enough.
|
76
|
+
# It may be nil.
|
77
|
+
#
|
78
|
+
# This method requires 'ruby_core_enhancements'. If 'debug_logging'
|
79
|
+
# is loaded and included in the current module, it will use that for
|
80
|
+
# logging.
|
81
|
+
def print_exception(current_location, exception, destination = nil)
|
82
|
+
if !exception.is_a?(SystemExit)
|
83
|
+
data = exception.backtrace_string(current_location)
|
84
|
+
if defined?(DebugLogging) && self.is_a?(DebugLogging)
|
85
|
+
error(data)
|
86
|
+
else
|
87
|
+
destination ||= STDERR
|
88
|
+
destination.puts(data)
|
89
|
+
destination.flush if destination.respond_to?(:flush)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# A wrapper around Thread.new that installs a default exception handler.
|
95
|
+
# If an uncaught exception is encountered, it will immediately log the
|
96
|
+
# exception and abort the entire program.
|
97
|
+
#
|
98
|
+
# Thread#abort_on_exception is also supposed to do that, but the problem
|
99
|
+
# is that it is implemented by forwarding the uncaught exception
|
100
|
+
# to the main thread, which may not expect that particular exception
|
101
|
+
# and may not handle it properly. The exception could be forwarded to
|
102
|
+
# the main thread during any point of the main thread's execution.
|
103
|
+
#
|
104
|
+
# This method requires 'thread' and 'ruby_core_enhancements'.
|
105
|
+
# If 'debug_logging' is loaded and included in the current module,
|
106
|
+
# it will use that for logging.
|
107
|
+
def create_thread_and_abort_on_exception(*args)
|
108
|
+
Thread.new do
|
109
|
+
Thread.current.abort_on_exception = true
|
110
|
+
begin
|
111
|
+
yield(*args)
|
112
|
+
rescue SystemExit
|
113
|
+
raise
|
114
|
+
rescue Exception => e
|
115
|
+
print_exception(nil, e)
|
116
|
+
exit(1)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def get_socket_address_type(address)
|
122
|
+
if address =~ %r{^unix:.}
|
123
|
+
return :unix
|
124
|
+
elsif address =~ %r{^tcp://.}
|
125
|
+
return :tcp
|
126
|
+
else
|
127
|
+
return :unknown
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def connect_to_server(address)
|
132
|
+
case get_socket_address_type(address)
|
133
|
+
when :unix
|
134
|
+
return UNIXSocket.new(address.sub(/^unix:/, ''))
|
135
|
+
when :tcp
|
136
|
+
host, port = address.sub(%r{^tcp://}, '').split(':', 2)
|
137
|
+
port = port.to_i
|
138
|
+
return TCPSocket.new(host, port)
|
139
|
+
else
|
140
|
+
raise ArgumentError, "Unknown socket address type for '#{address}'."
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def local_socket_address?(address)
|
145
|
+
case get_socket_address_type(address)
|
146
|
+
when :unix
|
147
|
+
return true
|
148
|
+
when :tcp
|
149
|
+
host, port = address.sub(%r{^tcp://}, '').split(':', 2)
|
150
|
+
return host == "127.0.0.1" || host == "::1" || host == "localhost"
|
151
|
+
else
|
152
|
+
raise ArgumentError, "Unknown socket address type for '#{address}'."
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
# Checks whether the given process exists.
|
157
|
+
def process_is_alive?(pid)
|
158
|
+
begin
|
159
|
+
Process.kill(0, pid)
|
160
|
+
return true
|
161
|
+
rescue Errno::ESRCH
|
162
|
+
return false
|
163
|
+
rescue SystemCallError => e
|
164
|
+
return true
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def require_option(hash, key)
|
169
|
+
if hash.has_key?(key)
|
170
|
+
return hash[key]
|
171
|
+
else
|
172
|
+
raise ArgumentError, "Option #{key.inspect} required"
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
def install_options_as_ivars(object, options, *keys)
|
177
|
+
keys.each do |key|
|
178
|
+
object.instance_variable_set("@#{key}", options[key])
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
# Returns a string which reports the backtraces for all threads,
|
183
|
+
# or if that's not supported the backtrace for the current thread.
|
184
|
+
def global_backtrace_report
|
185
|
+
if Kernel.respond_to?(:caller_for_all_threads)
|
186
|
+
all_thread_stacks = caller_for_all_threads
|
187
|
+
elsif Thread.respond_to?(:list) && Thread.public_method_defined?(:backtrace)
|
188
|
+
all_thread_stacks = {}
|
189
|
+
Thread.list.each do |thread|
|
190
|
+
all_thread_stacks[thread] = thread.backtrace
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
output = "========== Process #{Process.pid}: backtrace dump ==========\n"
|
195
|
+
if all_thread_stacks
|
196
|
+
all_thread_stacks.each_pair do |thread, stack|
|
197
|
+
if thread_name = thread[:name]
|
198
|
+
thread_name = "(#{thread_name})"
|
199
|
+
end
|
200
|
+
stack ||= ["(empty)"]
|
201
|
+
output << ("-" * 60) << "\n"
|
202
|
+
output << "# Thread: #{thread.inspect}#{thread_name}, "
|
203
|
+
if thread == Thread.main
|
204
|
+
output << "[main thread], "
|
205
|
+
end
|
206
|
+
if thread == Thread.current
|
207
|
+
output << "[current thread], "
|
208
|
+
end
|
209
|
+
output << "alive = #{thread.alive?}\n"
|
210
|
+
output << ("-" * 60) << "\n"
|
211
|
+
output << " " << stack.join("\n ")
|
212
|
+
output << "\n\n"
|
213
|
+
end
|
214
|
+
else
|
215
|
+
output << ("-" * 60) << "\n"
|
216
|
+
output << "# Current thread: #{Thread.current.inspect}\n"
|
217
|
+
output << ("-" * 60) << "\n"
|
218
|
+
output << " " << caller.join("\n ")
|
219
|
+
end
|
220
|
+
return output
|
221
|
+
end
|
222
|
+
|
223
|
+
####################################
|
224
|
+
end
|
193
225
|
|
194
226
|
end # module PhusionPassenger
|