passenger 4.0.48 → 4.0.49
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 +36 -2
- data/.travis.yml +1 -1
- data/CHANGELOG +16 -0
- data/Rakefile +0 -1
- data/build/apache2.rb +4 -4
- data/build/common_library.rb +18 -18
- data/build/cplusplus_support.rb +2 -2
- data/build/documentation.rb +1 -1
- data/build/integration_tests.rb +12 -4
- data/build/misc.rb +12 -7
- data/build/packaging.rb +14 -14
- data/build/preprocessor.rb +10 -10
- data/build/rake_extensions.rb +11 -11
- data/build/ruby_extension.rb +2 -2
- data/dev/ci/inituidgid +24 -0
- data/dev/ci/run_jenkins.sh +57 -0
- data/dev/ci/run_rpm_tests.sh +77 -0
- data/dev/{run_travis.sh → ci/run_travis.sh} +60 -4
- data/doc/Users guide Nginx.txt +2 -2
- data/doc/users_guide_snippets/environment_variables.txt +0 -2
- data/doc/users_guide_snippets/tips.txt +20 -1
- data/ext/apache2/Bucket.cpp +18 -18
- data/ext/apache2/Bucket.h +4 -4
- data/ext/apache2/Configuration.cpp +7 -7
- data/ext/apache2/Configuration.hpp +43 -43
- data/ext/apache2/DirectoryMapper.h +5 -5
- data/ext/apache2/Hooks.cpp +142 -142
- data/ext/apache2/MergeDirConfig.cpp +40 -40
- data/ext/common/Account.h +17 -17
- data/ext/common/AccountsDatabase.h +9 -9
- data/ext/common/AgentsStarter.cpp +2 -2
- data/ext/common/AgentsStarter.h +40 -40
- data/ext/common/ApplicationPool2/Common.h +10 -6
- data/ext/common/ApplicationPool2/ComponentInfo.h +2 -2
- data/ext/common/ApplicationPool2/DirectSpawner.h +17 -17
- data/ext/common/ApplicationPool2/DummySpawner.h +5 -5
- data/ext/common/ApplicationPool2/Group.h +54 -38
- data/ext/common/ApplicationPool2/Implementation.cpp +76 -49
- data/ext/common/ApplicationPool2/Options.h +98 -91
- data/ext/common/ApplicationPool2/Pool.h +70 -69
- data/ext/common/ApplicationPool2/Process.h +21 -21
- data/ext/common/ApplicationPool2/Session.h +11 -11
- data/ext/common/ApplicationPool2/SmartSpawner.h +60 -60
- data/ext/common/ApplicationPool2/Socket.h +19 -19
- data/ext/common/ApplicationPool2/Spawner.h +64 -72
- data/ext/common/ApplicationPool2/SpawnerFactory.h +4 -4
- data/ext/common/ApplicationPool2/SuperGroup.h +41 -41
- data/ext/common/BackgroundEventLoop.cpp +1 -1
- data/ext/common/BackgroundEventLoop.h +2 -2
- data/ext/common/Constants.h +1 -1
- data/ext/common/EventedBufferedInput.h +5 -5
- data/ext/common/EventedClient.h +51 -51
- data/ext/common/EventedMessageServer.h +39 -39
- data/ext/common/EventedServer.h +32 -32
- data/ext/common/Exceptions.h +23 -23
- data/ext/common/FileDescriptor.h +18 -18
- data/ext/common/Logging.cpp +1 -1
- data/ext/common/MessageClient.h +27 -27
- data/ext/common/MessageReadersWriters.h +79 -79
- data/ext/common/MessageServer.h +59 -59
- data/ext/common/RandomGenerator.h +12 -12
- data/ext/common/ResourceLocator.h +8 -8
- data/ext/common/SafeLibev.h +54 -25
- data/ext/common/ServerInstanceDir.h +31 -31
- data/ext/common/StaticString.h +50 -48
- data/ext/common/Utils.cpp +73 -78
- data/ext/common/Utils.h +6 -6
- data/ext/common/Utils/Base64.cpp +3 -3
- data/ext/common/Utils/Base64.h +7 -7
- data/ext/common/Utils/BlockingQueue.h +9 -9
- data/ext/common/Utils/BufferedIO.h +17 -17
- data/ext/common/Utils/CachedFileStat.hpp +16 -16
- data/ext/common/Utils/Dechunker.h +25 -25
- data/ext/common/Utils/FileChangeChecker.h +10 -10
- data/ext/common/Utils/MemZeroGuard.h +5 -5
- data/ext/common/Utils/MemoryBarrier.h +1 -1
- data/ext/common/Utils/MessageIO.h +61 -61
- data/ext/common/Utils/ProcessMetricsCollector.h +40 -40
- data/ext/common/Utils/ScopeGuard.h +7 -7
- data/ext/common/Utils/SpeedMeter.h +1 -1
- data/ext/common/Utils/StrIntUtils.cpp +13 -13
- data/ext/common/Utils/StrIntUtils.h +3 -3
- data/ext/common/Utils/StringScanning.h +5 -5
- data/ext/common/Utils/SystemMetricsCollector.h +2 -2
- data/ext/common/Utils/SystemTime.h +10 -10
- data/ext/common/Utils/Template.h +2 -2
- data/ext/common/Utils/Timer.h +6 -6
- data/ext/common/Utils/VariantMap.h +29 -29
- data/ext/common/agents/Base.cpp +19 -19
- data/ext/common/agents/HelperAgent/AgentOptions.h +1 -1
- data/ext/common/agents/HelperAgent/FileBackedPipe.h +6 -6
- data/ext/common/agents/HelperAgent/Main.cpp +44 -43
- data/ext/common/agents/HelperAgent/RequestHandler.cpp +4 -4
- data/ext/common/agents/HelperAgent/RequestHandler.h +29 -28
- data/ext/common/agents/HelperAgent/ScgiRequestParser.h +56 -50
- data/ext/common/agents/LoggingAgent/AdminController.h +8 -8
- data/ext/common/agents/LoggingAgent/DataStoreId.h +17 -17
- data/ext/common/agents/LoggingAgent/FilterSupport.h +167 -167
- data/ext/common/agents/LoggingAgent/LoggingServer.h +122 -122
- data/ext/common/agents/LoggingAgent/Main.cpp +7 -7
- data/ext/common/agents/LoggingAgent/RemoteSender.h +54 -54
- data/ext/common/agents/SpawnPreparer.cpp +4 -4
- data/ext/common/agents/TempDirToucher.c +2 -2
- data/ext/common/agents/Watchdog/AgentWatcher.cpp +47 -47
- data/ext/common/agents/Watchdog/HelperAgentWatcher.cpp +7 -7
- data/ext/common/agents/Watchdog/LoggingAgentWatcher.cpp +7 -7
- data/ext/common/agents/Watchdog/Main.cpp +22 -22
- data/ext/common/agents/Watchdog/ServerInstanceDirToucher.cpp +9 -9
- data/ext/libeio/eio.c +1 -1
- data/ext/nginx/Configuration.c +30 -30
- data/ext/nginx/Configuration.h +1 -1
- data/ext/nginx/ContentHandler.c +54 -54
- data/ext/nginx/ContentHandler.h +3 -3
- data/ext/nginx/StaticContentHandler.c +2 -2
- data/ext/nginx/ngx_http_passenger_module.c +21 -21
- data/ext/oxt/detail/backtrace_enabled.hpp +1 -1
- data/ext/oxt/detail/context.hpp +1 -1
- data/ext/oxt/detail/spin_lock_darwin.hpp +4 -4
- data/ext/oxt/detail/spin_lock_gcc_x86.hpp +3 -3
- data/ext/oxt/detail/spin_lock_pthreads.hpp +4 -4
- data/ext/oxt/detail/tracable_exception_disabled.hpp +1 -1
- data/ext/oxt/dynamic_thread_group.hpp +18 -18
- data/ext/oxt/implementation.cpp +9 -8
- data/ext/oxt/macros.hpp +2 -2
- data/ext/oxt/system_calls.cpp +11 -11
- data/ext/oxt/system_calls.hpp +13 -13
- data/ext/oxt/thread.hpp +22 -14
- data/ext/ruby/passenger_native_support.c +55 -55
- data/lib/phusion_passenger.rb +24 -24
- data/lib/phusion_passenger/common_library.rb +2 -0
- data/lib/phusion_passenger/loader_shared_helpers.rb +18 -18
- data/lib/phusion_passenger/packaging.rb +9 -4
- data/lib/phusion_passenger/platform_info/apache.rb +45 -31
- data/lib/phusion_passenger/platform_info/compiler.rb +11 -11
- data/lib/phusion_passenger/rack/thread_handler_extension.rb +1 -1
- data/lib/phusion_passenger/request_handler/thread_handler.rb +8 -8
- data/lib/phusion_passenger/standalone/app_finder.rb +16 -16
- data/lib/phusion_passenger/standalone/command.rb +22 -22
- data/packaging/rpm/LICENSE.txt +19 -0
- data/packaging/rpm/Makefile +13 -0
- data/packaging/rpm/README.md +41 -0
- data/packaging/rpm/Vagrantfile +38 -0
- data/{rpm/Vagrantfile → packaging/rpm/Vagrantfile.centos} +0 -0
- data/packaging/rpm/build +170 -0
- data/packaging/rpm/create_project +41 -0
- data/packaging/rpm/git_update +88 -0
- data/packaging/rpm/image/Dockerfile +37 -0
- data/packaging/rpm/image/Gemfile +3 -0
- data/packaging/rpm/image/Gemfile.lock +12 -0
- data/packaging/rpm/image/RPM-GPG-KEY-amazon-ga +19 -0
- data/packaging/rpm/image/amazon2014-i386.cfg +96 -0
- data/packaging/rpm/image/amazon2014-x86_64.cfg +96 -0
- data/packaging/rpm/image/site-defaults.cfg +168 -0
- data/packaging/rpm/internal/build_tasks.rb +238 -0
- data/packaging/rpm/internal/dummygpg +11 -0
- data/packaging/rpm/internal/exec_build +42 -0
- data/packaging/rpm/internal/get_distro_arch +14 -0
- data/packaging/rpm/internal/get_distro_id +10 -0
- data/packaging/rpm/internal/git_update +27 -0
- data/packaging/rpm/internal/inituidgid +17 -0
- data/packaging/rpm/internal/my_init +344 -0
- data/packaging/rpm/internal/python27 +3 -0
- data/packaging/rpm/internal/repo_update +46 -0
- data/packaging/rpm/internal/setuser +26 -0
- data/packaging/rpm/internal/tracking_helper +40 -0
- data/packaging/rpm/jenkins_release +99 -0
- data/packaging/rpm/lib/build_tasks_support.rb +402 -0
- data/packaging/rpm/lib/preprocessor.rb +341 -0
- data/packaging/rpm/nginx_spec/404.html +119 -0
- data/packaging/rpm/nginx_spec/50x.html +119 -0
- data/packaging/rpm/nginx_spec/index.html +116 -0
- data/packaging/rpm/nginx_spec/nginx-auto-cc-gcc.patch +13 -0
- data/packaging/rpm/nginx_spec/nginx-logo.png +0 -0
- data/packaging/rpm/nginx_spec/nginx-upgrade +13 -0
- data/packaging/rpm/nginx_spec/nginx-upgrade.8 +151 -0
- data/packaging/rpm/nginx_spec/nginx.conf +131 -0
- data/packaging/rpm/nginx_spec/nginx.init +144 -0
- data/packaging/rpm/nginx_spec/nginx.logrotate +13 -0
- data/packaging/rpm/nginx_spec/nginx.service +15 -0
- data/packaging/rpm/nginx_spec/nginx.spec.template +559 -0
- data/packaging/rpm/nginx_spec/nginx.sysconfig +4 -0
- data/packaging/rpm/nginx_spec/passenger.conf +9 -0
- data/packaging/rpm/nginx_spec/poweredby.png +0 -0
- data/{rpm → packaging/rpm/passenger_spec}/apache-passenger.conf.in +0 -0
- data/{rpm → packaging/rpm/passenger_spec}/config.json +0 -0
- data/{rpm → packaging/rpm/passenger_spec}/passenger.logrotate +0 -0
- data/{rpm → packaging/rpm/passenger_spec}/passenger.spec.template +58 -31
- data/{rpm → packaging/rpm/passenger_spec}/passenger_dynamic_thread_group.patch +0 -0
- data/{rpm → packaging/rpm/passenger_spec}/passenger_tests_default_config_example.patch +0 -0
- data/{rpm → packaging/rpm/passenger_spec}/rubygem-passenger-4.0.18-GLIBC_HAVE_LONG_LONG.patch +0 -0
- data/{rpm → packaging/rpm/passenger_spec}/rubygem-passenger-4.0.18-gcc47-include-sys_types.patch +0 -0
- data/packaging/rpm/repo_update +114 -0
- data/packaging/rpm/setup-system +60 -0
- data/packaging/rpm/shell +10 -0
- data/resources/templates/standalone/config.erb +3 -1
- data/test/config.json.rpm-automation +1 -1
- data/test/cxx/ApplicationPool2/DirectSpawnerTest.cpp +11 -11
- data/test/cxx/ApplicationPool2/OptionsTest.cpp +5 -5
- data/test/cxx/ApplicationPool2/PoolTest.cpp +129 -89
- data/test/cxx/ApplicationPool2/ProcessTest.cpp +15 -15
- data/test/cxx/ApplicationPool2/SmartSpawnerTest.cpp +22 -22
- data/test/cxx/ApplicationPool2/SpawnerTestCases.cpp +11 -11
- data/test/cxx/ScgiRequestParserTest.cpp +75 -61
- data/test/cxx/UtilsTest.cpp +86 -85
- data/test/gdbinit.example +3 -0
- data/test/integration_tests/nginx_tests.rb +3 -3
- data/test/integration_tests/source_packaging_test.rb +3 -1
- data/test/stub/nginx/nginx.conf.erb +8 -1
- data/test/support/nginx_controller.rb +7 -7
- metadata +62 -17
- metadata.gz.asc +7 -7
- data/build/rpm.rb +0 -128
- data/dev/rpmtool +0 -21
- data/dev/test_rpm_packaging.sh +0 -28
- data/rpm/get_distro_id.py +0 -4
@@ -30,6 +30,8 @@
|
|
30
30
|
#include <limits.h>
|
31
31
|
#include <unistd.h>
|
32
32
|
#include <boost/make_shared.hpp>
|
33
|
+
#include <boost/ref.hpp>
|
34
|
+
#include <boost/cstdint.hpp>
|
33
35
|
#include <boost/date_time/posix_time/posix_time_types.hpp>
|
34
36
|
#include <oxt/backtrace.hpp>
|
35
37
|
#include <ApplicationPool2/Pool.h>
|
@@ -38,6 +40,7 @@
|
|
38
40
|
#include <ApplicationPool2/PipeWatcher.h>
|
39
41
|
#include <ApplicationPool2/ErrorRenderer.h>
|
40
42
|
#include <Exceptions.h>
|
43
|
+
#include <Hooks.h>
|
41
44
|
#include <MessageReadersWriters.h>
|
42
45
|
#include <Utils.h>
|
43
46
|
#include <Utils/IOUtils.h>
|
@@ -65,28 +68,28 @@ copyException(const tracable_exception &e) {
|
|
65
68
|
TRY_COPY_EXCEPTION(FileSystemException);
|
66
69
|
TRY_COPY_EXCEPTION(TimeRetrievalException);
|
67
70
|
TRY_COPY_EXCEPTION(SystemException);
|
68
|
-
|
71
|
+
|
69
72
|
TRY_COPY_EXCEPTION(FileNotFoundException);
|
70
73
|
TRY_COPY_EXCEPTION(EOFException);
|
71
74
|
TRY_COPY_EXCEPTION(IOException);
|
72
|
-
|
75
|
+
|
73
76
|
TRY_COPY_EXCEPTION(ConfigurationException);
|
74
|
-
|
77
|
+
|
75
78
|
TRY_COPY_EXCEPTION(RequestQueueFullException);
|
76
79
|
TRY_COPY_EXCEPTION(GetAbortedException);
|
77
80
|
TRY_COPY_EXCEPTION(SpawnException);
|
78
|
-
|
81
|
+
|
79
82
|
TRY_COPY_EXCEPTION(InvalidModeStringException);
|
80
83
|
TRY_COPY_EXCEPTION(ArgumentException);
|
81
|
-
|
84
|
+
|
82
85
|
TRY_COPY_EXCEPTION(RuntimeException);
|
83
|
-
|
86
|
+
|
84
87
|
TRY_COPY_EXCEPTION(TimeoutException);
|
85
|
-
|
88
|
+
|
86
89
|
TRY_COPY_EXCEPTION(NonExistentUserException);
|
87
90
|
TRY_COPY_EXCEPTION(NonExistentGroupException);
|
88
91
|
TRY_COPY_EXCEPTION(SecurityException);
|
89
|
-
|
92
|
+
|
90
93
|
TRY_COPY_EXCEPTION(SyntaxError);
|
91
94
|
|
92
95
|
TRY_COPY_EXCEPTION(boost::thread_interrupted);
|
@@ -107,28 +110,28 @@ rethrowException(const ExceptionPtr &e) {
|
|
107
110
|
TRY_RETHROW_EXCEPTION(FileSystemException);
|
108
111
|
TRY_RETHROW_EXCEPTION(TimeRetrievalException);
|
109
112
|
TRY_RETHROW_EXCEPTION(SystemException);
|
110
|
-
|
113
|
+
|
111
114
|
TRY_RETHROW_EXCEPTION(FileNotFoundException);
|
112
115
|
TRY_RETHROW_EXCEPTION(EOFException);
|
113
116
|
TRY_RETHROW_EXCEPTION(IOException);
|
114
|
-
|
117
|
+
|
115
118
|
TRY_RETHROW_EXCEPTION(ConfigurationException);
|
116
|
-
|
119
|
+
|
117
120
|
TRY_RETHROW_EXCEPTION(SpawnException);
|
118
121
|
TRY_RETHROW_EXCEPTION(RequestQueueFullException);
|
119
122
|
TRY_RETHROW_EXCEPTION(GetAbortedException);
|
120
|
-
|
123
|
+
|
121
124
|
TRY_RETHROW_EXCEPTION(InvalidModeStringException);
|
122
125
|
TRY_RETHROW_EXCEPTION(ArgumentException);
|
123
|
-
|
126
|
+
|
124
127
|
TRY_RETHROW_EXCEPTION(RuntimeException);
|
125
|
-
|
128
|
+
|
126
129
|
TRY_RETHROW_EXCEPTION(TimeoutException);
|
127
|
-
|
130
|
+
|
128
131
|
TRY_RETHROW_EXCEPTION(NonExistentUserException);
|
129
132
|
TRY_RETHROW_EXCEPTION(NonExistentGroupException);
|
130
133
|
TRY_RETHROW_EXCEPTION(SecurityException);
|
131
|
-
|
134
|
+
|
132
135
|
TRY_RETHROW_EXCEPTION(SyntaxError);
|
133
136
|
|
134
137
|
TRY_RETHROW_EXCEPTION(boost::lock_error);
|
@@ -140,7 +143,7 @@ rethrowException(const ExceptionPtr &e) {
|
|
140
143
|
TRY_RETHROW_EXCEPTION(boost::thread_interrupted);
|
141
144
|
TRY_RETHROW_EXCEPTION(boost::thread_exception);
|
142
145
|
TRY_RETHROW_EXCEPTION(boost::condition_error);
|
143
|
-
|
146
|
+
|
144
147
|
throw tracable_exception(*e);
|
145
148
|
}
|
146
149
|
|
@@ -282,6 +285,20 @@ void processAndLogNewSpawnException(SpawnException &e, const Options &options,
|
|
282
285
|
}
|
283
286
|
stream << " Message from application: " << appMessage << "\n";
|
284
287
|
P_ERROR(stream.str());
|
288
|
+
|
289
|
+
if (config->agentsOptions != NULL) {
|
290
|
+
HookScriptOptions hOptions;
|
291
|
+
hOptions.name = "spawn_failed";
|
292
|
+
hOptions.spec = config->agentsOptions->get("hook_spawn_failed", false);
|
293
|
+
hOptions.agentsOptions = config->agentsOptions;
|
294
|
+
hOptions.environment.push_back(make_pair("PASSENGER_APP_ROOT", options.appRoot));
|
295
|
+
hOptions.environment.push_back(make_pair("PASSENGER_APP_GROUP_NAME", options.getAppGroupName()));
|
296
|
+
hOptions.environment.push_back(make_pair("PASSENGER_ERROR_MESSAGE", e.what()));
|
297
|
+
hOptions.environment.push_back(make_pair("PASSENGER_ERROR_ID", errorId));
|
298
|
+
hOptions.environment.push_back(make_pair("PASSENGER_APP_ERROR_MESSAGE", appMessage));
|
299
|
+
oxt::thread(boost::bind(runHookScripts, hOptions),
|
300
|
+
"Hook: spawn_failed", 256 * 1024);
|
301
|
+
}
|
285
302
|
}
|
286
303
|
|
287
304
|
|
@@ -337,7 +354,7 @@ SuperGroup::realDoInitialize(const Options &options, unsigned int generation) {
|
|
337
354
|
ExceptionPtr exception;
|
338
355
|
|
339
356
|
PoolPtr pool = getPool();
|
340
|
-
|
357
|
+
|
341
358
|
P_TRACE(2, "Initializing SuperGroup " << inspect() << " in the background...");
|
342
359
|
try {
|
343
360
|
componentInfos = loadComponentInfos(options);
|
@@ -355,7 +372,7 @@ SuperGroup::realDoInitialize(const Options &options, unsigned int generation) {
|
|
355
372
|
processAndLogNewSpawnException(*spawnException, options,
|
356
373
|
pool->getSpawnerConfig());
|
357
374
|
}
|
358
|
-
|
375
|
+
|
359
376
|
Pool::DebugSupportPtr debug = pool->debugSupport;
|
360
377
|
vector<Callback> actions;
|
361
378
|
{
|
@@ -374,14 +391,14 @@ SuperGroup::realDoInitialize(const Options &options, unsigned int generation) {
|
|
374
391
|
P_TRACE(2, "Initialization of SuperGroup " << inspect() << " almost done; grabbed lock");
|
375
392
|
assert(state == INITIALIZING);
|
376
393
|
verifyInvariants();
|
377
|
-
|
394
|
+
|
378
395
|
if (componentInfos.empty()) {
|
379
396
|
/* Somehow initialization failed. Maybe something has deleted
|
380
397
|
* the supergroup files while we're working.
|
381
398
|
*/
|
382
399
|
assert(exception != NULL);
|
383
400
|
setState(DESTROYED);
|
384
|
-
|
401
|
+
|
385
402
|
actions.reserve(getWaitlist.size());
|
386
403
|
while (!getWaitlist.empty()) {
|
387
404
|
const GetWaiter &waiter = getWaitlist.front();
|
@@ -403,7 +420,7 @@ SuperGroup::realDoInitialize(const Options &options, unsigned int generation) {
|
|
403
420
|
setState(READY);
|
404
421
|
assignGetWaitlistToGroups(actions);
|
405
422
|
}
|
406
|
-
|
423
|
+
|
407
424
|
verifyInvariants();
|
408
425
|
P_TRACE(2, "Done initializing SuperGroup " << inspect());
|
409
426
|
}
|
@@ -419,14 +436,14 @@ SuperGroup::realDoRestart(const Options &options, unsigned int generation) {
|
|
419
436
|
TRACE_POINT();
|
420
437
|
vector<ComponentInfo> componentInfos = loadComponentInfos(options);
|
421
438
|
vector<ComponentInfo>::const_iterator it;
|
422
|
-
|
439
|
+
|
423
440
|
PoolPtr pool = getPool();
|
424
441
|
Pool::DebugSupportPtr debug = pool->debugSupport;
|
425
442
|
if (debug != NULL && debug->superGroup) {
|
426
443
|
debug->debugger->send("About to finish SuperGroup restart");
|
427
444
|
debug->messages->recv("Proceed with restarting SuperGroup");
|
428
445
|
}
|
429
|
-
|
446
|
+
|
430
447
|
boost::unique_lock<boost::mutex> lock(getPoolSyncher(pool));
|
431
448
|
if (OXT_UNLIKELY(this->generation != generation)) {
|
432
449
|
return;
|
@@ -434,14 +451,14 @@ SuperGroup::realDoRestart(const Options &options, unsigned int generation) {
|
|
434
451
|
|
435
452
|
assert(state == RESTARTING);
|
436
453
|
verifyInvariants();
|
437
|
-
|
454
|
+
|
438
455
|
vector<GroupPtr> allGroups;
|
439
456
|
vector<GroupPtr> updatedGroups;
|
440
457
|
vector<GroupPtr> newGroups;
|
441
458
|
vector<GroupPtr>::const_iterator g_it;
|
442
459
|
vector<Callback> actions;
|
443
460
|
this->options = options;
|
444
|
-
|
461
|
+
|
445
462
|
// Update the component information for existing groups.
|
446
463
|
UPDATE_TRACE_POINT();
|
447
464
|
for (it = componentInfos.begin(); it != componentInfos.end(); it++) {
|
@@ -464,22 +481,22 @@ SuperGroup::realDoRestart(const Options &options, unsigned int generation) {
|
|
464
481
|
// allGroups must be in the same order as componentInfos.
|
465
482
|
allGroups.push_back(group);
|
466
483
|
}
|
467
|
-
|
484
|
+
|
468
485
|
// Some components might have been deleted, so delete the
|
469
486
|
// corresponding groups.
|
470
487
|
detachAllGroups(groups, actions);
|
471
|
-
|
488
|
+
|
472
489
|
// Tell all previous existing groups to restart.
|
473
490
|
for (g_it = updatedGroups.begin(); g_it != updatedGroups.end(); g_it++) {
|
474
491
|
GroupPtr group = *g_it;
|
475
492
|
group->restart(options);
|
476
493
|
}
|
477
|
-
|
494
|
+
|
478
495
|
groups = allGroups;
|
479
496
|
defaultGroup = findDefaultGroup(allGroups);
|
480
497
|
setState(READY);
|
481
498
|
assignGetWaitlistToGroups(actions);
|
482
|
-
|
499
|
+
|
483
500
|
UPDATE_TRACE_POINT();
|
484
501
|
verifyInvariants();
|
485
502
|
lock.unlock();
|
@@ -491,6 +508,7 @@ Group::Group(const SuperGroupPtr &_superGroup, const Options &options, const Com
|
|
491
508
|
: superGroup(_superGroup),
|
492
509
|
name(_superGroup->name + "#" + info.name),
|
493
510
|
secret(generateSecret(_superGroup)),
|
511
|
+
uuid(generateUuid(_superGroup)),
|
494
512
|
componentInfo(info)
|
495
513
|
{
|
496
514
|
enabledCount = 0;
|
@@ -565,7 +583,7 @@ Group::onSessionClose(const ProcessPtr &process, Session *session) {
|
|
565
583
|
P_TRACE(2, "Session closed for process " << process->inspect());
|
566
584
|
verifyInvariants();
|
567
585
|
UPDATE_TRACE_POINT();
|
568
|
-
|
586
|
+
|
569
587
|
/* Update statistics. */
|
570
588
|
process->sessionClosed(session);
|
571
589
|
assert(process->getLifeStatus() == Process::ALIVE);
|
@@ -603,6 +621,7 @@ Group::onSessionClose(const ProcessPtr &process, Session *session) {
|
|
603
621
|
&& enabledCount > 0;
|
604
622
|
|
605
623
|
if (shouldDetach || shouldDisable) {
|
624
|
+
UPDATE_TRACE_POINT();
|
606
625
|
vector<Callback> actions;
|
607
626
|
|
608
627
|
if (shouldDetach) {
|
@@ -630,12 +649,14 @@ Group::onSessionClose(const ProcessPtr &process, Session *session) {
|
|
630
649
|
removeFromDisableWaitlist(process, DR_SUCCESS, actions);
|
631
650
|
maybeInitiateOobw(process);
|
632
651
|
}
|
633
|
-
|
652
|
+
|
634
653
|
pool->fullVerifyInvariants();
|
635
654
|
lock.unlock();
|
636
655
|
runAllActions(actions);
|
637
656
|
|
638
657
|
} else {
|
658
|
+
UPDATE_TRACE_POINT();
|
659
|
+
|
639
660
|
// This could change process->enabled.
|
640
661
|
maybeInitiateOobw(process);
|
641
662
|
|
@@ -695,7 +716,7 @@ Group::maybeInitiateOobw(const ProcessPtr &process) {
|
|
695
716
|
void
|
696
717
|
Group::lockAndMaybeInitiateOobw(const ProcessPtr &process, DisableResult result, GroupPtr self) {
|
697
718
|
TRACE_POINT();
|
698
|
-
|
719
|
+
|
699
720
|
// Standard resource management boilerplate stuff...
|
700
721
|
PoolPtr pool = getPool();
|
701
722
|
boost::unique_lock<boost::mutex> lock(pool->syncher);
|
@@ -766,10 +787,10 @@ Group::initiateOobw(const ProcessPtr &process) {
|
|
766
787
|
P_BUG("Unexpected disable() result " << result);
|
767
788
|
}
|
768
789
|
}
|
769
|
-
|
790
|
+
|
770
791
|
assert(process->enabled == Process::DISABLED);
|
771
792
|
assert(process->sessions == 0);
|
772
|
-
|
793
|
+
|
773
794
|
P_DEBUG("Initiating OOBW request for process " << process->inspect());
|
774
795
|
interruptableThreads.create_thread(
|
775
796
|
boost::bind(&Group::spawnThreadOOBWRequest, this, shared_from_this(), process),
|
@@ -795,7 +816,7 @@ Group::spawnThreadOOBWRequest(GroupPtr self, ProcessPtr process) {
|
|
795
816
|
debug->debugger->send("OOBW request about to start");
|
796
817
|
debug->messages->recv("Proceed with OOBW request");
|
797
818
|
}
|
798
|
-
|
819
|
+
|
799
820
|
UPDATE_TRACE_POINT();
|
800
821
|
{
|
801
822
|
// Standard resource management boilerplate stuff...
|
@@ -816,13 +837,13 @@ Group::spawnThreadOOBWRequest(GroupPtr self, ProcessPtr process) {
|
|
816
837
|
}
|
817
838
|
return;
|
818
839
|
}
|
819
|
-
|
840
|
+
|
820
841
|
assert(process->oobwStatus == Process::OOBW_IN_PROGRESS);
|
821
842
|
assert(process->sessions == 0);
|
822
843
|
socket = process->sessionSockets.top();
|
823
844
|
assert(socket != NULL);
|
824
845
|
}
|
825
|
-
|
846
|
+
|
826
847
|
UPDATE_TRACE_POINT();
|
827
848
|
unsigned long long timeout = 1000 * 1000 * 60; // 1 min
|
828
849
|
try {
|
@@ -835,22 +856,22 @@ Group::spawnThreadOOBWRequest(GroupPtr self, ProcessPtr process) {
|
|
835
856
|
connection = socket->checkoutConnection();
|
836
857
|
connection.fail = true;
|
837
858
|
ScopeGuard guard(boost::bind(&Socket::checkinConnection, socket, connection));
|
838
|
-
|
859
|
+
|
839
860
|
// This is copied from RequestHandler when it is sending data using the
|
840
861
|
// "session" protocol.
|
841
|
-
char sizeField[sizeof(uint32_t)];
|
862
|
+
char sizeField[sizeof(boost::uint32_t)];
|
842
863
|
SmallVector<StaticString, 10> data;
|
843
864
|
|
844
|
-
data.push_back(StaticString(sizeField, sizeof(uint32_t)));
|
865
|
+
data.push_back(StaticString(sizeField, sizeof(boost::uint32_t)));
|
845
866
|
data.push_back(makeStaticStringWithNull("REQUEST_METHOD"));
|
846
867
|
data.push_back(makeStaticStringWithNull("OOBW"));
|
847
868
|
|
848
869
|
data.push_back(makeStaticStringWithNull("PASSENGER_CONNECT_PASSWORD"));
|
849
870
|
data.push_back(makeStaticStringWithNull(process->connectPassword));
|
850
871
|
|
851
|
-
uint32_t dataSize = 0;
|
872
|
+
boost::uint32_t dataSize = 0;
|
852
873
|
for (unsigned int i = 1; i < data.size(); i++) {
|
853
|
-
dataSize += (uint32_t) data[i].size();
|
874
|
+
dataSize += (boost::uint32_t) data[i].size();
|
854
875
|
}
|
855
876
|
Uint32Message::generate(sizeField, dataSize);
|
856
877
|
|
@@ -864,7 +885,7 @@ Group::spawnThreadOOBWRequest(GroupPtr self, ProcessPtr process) {
|
|
864
885
|
} catch (const TimeoutException &e) {
|
865
886
|
P_ERROR("*** ERROR: " << e.what() << "\n" << e.backtrace());
|
866
887
|
}
|
867
|
-
|
888
|
+
|
868
889
|
UPDATE_TRACE_POINT();
|
869
890
|
vector<Callback> actions;
|
870
891
|
{
|
@@ -874,7 +895,7 @@ Group::spawnThreadOOBWRequest(GroupPtr self, ProcessPtr process) {
|
|
874
895
|
if (OXT_UNLIKELY(!process->isAlive() || !isAlive())) {
|
875
896
|
return;
|
876
897
|
}
|
877
|
-
|
898
|
+
|
878
899
|
process->oobwStatus = Process::OOBW_NOT_ACTIVE;
|
879
900
|
if (process->enabled == Process::DISABLED) {
|
880
901
|
enable(process, actions);
|
@@ -924,7 +945,7 @@ Group::spawnThreadRealMain(const SpawnerPtr &spawner, const Options &options, un
|
|
924
945
|
|
925
946
|
PoolPtr pool = getPool();
|
926
947
|
Pool::DebugSupportPtr debug = pool->debugSupport;
|
927
|
-
|
948
|
+
|
928
949
|
bool done = false;
|
929
950
|
while (!done) {
|
930
951
|
bool shouldFail = false;
|
@@ -942,7 +963,7 @@ Group::spawnThreadRealMain(const SpawnerPtr &spawner, const Options &options, un
|
|
942
963
|
P_DEBUG("Begin spawn loop iteration " << iteration);
|
943
964
|
debug->debugger->send("Begin spawn loop iteration " +
|
944
965
|
iteration);
|
945
|
-
|
966
|
+
|
946
967
|
vector<string> cases;
|
947
968
|
cases.push_back("Proceed with spawn loop iteration " + iteration);
|
948
969
|
cases.push_back("Fail spawn loop iteration " + iteration);
|
@@ -1094,6 +1115,7 @@ Group::restart(const Options &options, RestartMethod method) {
|
|
1094
1115
|
processesBeingSpawned = 0;
|
1095
1116
|
m_spawning = false;
|
1096
1117
|
m_restarting = true;
|
1118
|
+
uuid = generateUuid(getSuperGroup());
|
1097
1119
|
detachAll(actions);
|
1098
1120
|
getPool()->interruptableThreads.create_thread(
|
1099
1121
|
boost::bind(&Group::finalizeRestart, this, shared_from_this(),
|
@@ -1153,7 +1175,7 @@ Group::finalizeRestart(GroupPtr self, Options options, RestartMethod method,
|
|
1153
1175
|
pool->fullVerifyInvariants();
|
1154
1176
|
assert(m_restarting);
|
1155
1177
|
UPDATE_TRACE_POINT();
|
1156
|
-
|
1178
|
+
|
1157
1179
|
// Atomically swap the new spawner with the old one.
|
1158
1180
|
resetOptions(options);
|
1159
1181
|
oldSpawner = spawner;
|
@@ -1376,6 +1398,11 @@ Group::generateSecret(const SuperGroupPtr &superGroup) {
|
|
1376
1398
|
return superGroup->getPool()->getRandomGenerator()->generateAsciiString(43);
|
1377
1399
|
}
|
1378
1400
|
|
1401
|
+
string
|
1402
|
+
Group::generateUuid(const SuperGroupPtr &superGroup) {
|
1403
|
+
return superGroup->getPool()->getRandomGenerator()->generateAsciiString(20);
|
1404
|
+
}
|
1405
|
+
|
1379
1406
|
|
1380
1407
|
PoolPtr
|
1381
1408
|
Process::getPool() const {
|
@@ -1508,7 +1535,7 @@ PipeWatcher::threadMain() {
|
|
1508
1535
|
while (!this_thread::interruption_requested()) {
|
1509
1536
|
char buf[1024 * 8];
|
1510
1537
|
ssize_t ret;
|
1511
|
-
|
1538
|
+
|
1512
1539
|
UPDATE_TRACE_POINT();
|
1513
1540
|
ret = syscalls::read(fd, buf, sizeof(buf));
|
1514
1541
|
if (ret == 0) {
|
@@ -59,47 +59,47 @@ using namespace boost;
|
|
59
59
|
* "!STARTUP_FILE!", then the startup file's group will be used. Otherwise,
|
60
60
|
* the primary group of the user that the application process will run as,
|
61
61
|
* will be used as group.
|
62
|
-
*
|
62
|
+
*
|
63
63
|
* If the user or group that the application process attempts to switch to
|
64
64
|
* doesn't exist, then <em>defaultUser</em> and <em>defaultGroup</em>, respectively,
|
65
65
|
* will be used.
|
66
|
-
*
|
66
|
+
*
|
67
67
|
* Phusion Passenger will attempt to avoid running the application process as
|
68
68
|
* root: if <em>user</em> or <em>group</em> is set to the root user or the root group,
|
69
69
|
* or if the startup file is owned by root, then <em>defaultUser</em> and
|
70
70
|
* <em>defaultGroup</em> will be used instead.
|
71
|
-
*
|
71
|
+
*
|
72
72
|
* All this only happen if Phusion Passenger has root privileges. If not, then
|
73
73
|
* these options have no effect.
|
74
74
|
*/
|
75
75
|
class Options {
|
76
76
|
private:
|
77
77
|
shared_array<char> storage;
|
78
|
-
|
78
|
+
|
79
79
|
vector<const StaticString *> getStringFields() const {
|
80
80
|
vector<const StaticString *> result;
|
81
81
|
result.reserve(20);
|
82
|
-
|
82
|
+
|
83
83
|
result.push_back(&appRoot);
|
84
84
|
result.push_back(&appGroupName);
|
85
85
|
result.push_back(&appType);
|
86
86
|
result.push_back(&startCommand);
|
87
87
|
result.push_back(&startupFile);
|
88
88
|
result.push_back(&processTitle);
|
89
|
-
|
89
|
+
|
90
90
|
result.push_back(&environment);
|
91
91
|
result.push_back(&baseURI);
|
92
92
|
result.push_back(&spawnMethod);
|
93
|
-
|
93
|
+
|
94
94
|
result.push_back(&user);
|
95
95
|
result.push_back(&group);
|
96
96
|
result.push_back(&defaultUser);
|
97
97
|
result.push_back(&defaultGroup);
|
98
98
|
result.push_back(&restartDir);
|
99
|
-
|
99
|
+
|
100
100
|
result.push_back(&preexecChroot);
|
101
101
|
result.push_back(&postexecChroot);
|
102
|
-
|
102
|
+
|
103
103
|
result.push_back(&ruby);
|
104
104
|
result.push_back(&python);
|
105
105
|
result.push_back(&nodejs);
|
@@ -110,10 +110,10 @@ private:
|
|
110
110
|
result.push_back(&hostName);
|
111
111
|
result.push_back(&uri);
|
112
112
|
result.push_back(&unionStationKey);
|
113
|
-
|
113
|
+
|
114
114
|
return result;
|
115
115
|
}
|
116
|
-
|
116
|
+
|
117
117
|
static inline void
|
118
118
|
appendKeyValue(vector<string> &vec, const char *key, const StaticString &value) {
|
119
119
|
if (!value.empty()) {
|
@@ -121,44 +121,44 @@ private:
|
|
121
121
|
vec.push_back(value.toString());
|
122
122
|
}
|
123
123
|
}
|
124
|
-
|
124
|
+
|
125
125
|
static inline void
|
126
126
|
appendKeyValue(vector<string> &vec, const char *key, const char *value) {
|
127
127
|
vec.push_back(key);
|
128
128
|
vec.push_back(value);
|
129
129
|
}
|
130
|
-
|
130
|
+
|
131
131
|
static inline void
|
132
132
|
appendKeyValue2(vector<string> &vec, const char *key, long value) {
|
133
133
|
vec.push_back(key);
|
134
134
|
vec.push_back(toString(value));
|
135
135
|
}
|
136
|
-
|
136
|
+
|
137
137
|
static inline void
|
138
138
|
appendKeyValue3(vector<string> &vec, const char *key, unsigned long value) {
|
139
139
|
vec.push_back(key);
|
140
140
|
vec.push_back(toString(value));
|
141
141
|
}
|
142
|
-
|
142
|
+
|
143
143
|
static inline void
|
144
144
|
appendKeyValue4(vector<string> &vec, const char *key, bool value) {
|
145
145
|
vec.push_back(key);
|
146
146
|
vec.push_back(value ? "true" : "false");
|
147
147
|
}
|
148
|
-
|
148
|
+
|
149
149
|
public:
|
150
150
|
/*********** Spawn options that should be set by the caller ***********
|
151
151
|
* These are the options that are relevant while spawning an application
|
152
152
|
* process. These options are only used during spawning.
|
153
153
|
*/
|
154
|
-
|
154
|
+
|
155
155
|
/**
|
156
156
|
* The root directory of the application to spawn. In case of a Ruby on Rails
|
157
157
|
* application, this is the folder that contains 'app/', 'public/', 'config/',
|
158
158
|
* etc. This must be a valid directory, but the path does not have to be absolute.
|
159
159
|
*/
|
160
160
|
StaticString appRoot;
|
161
|
-
|
161
|
+
|
162
162
|
/**
|
163
163
|
* A name used by ApplicationPool to uniquely identify an application.
|
164
164
|
* If one tries to get() from the application pool with name "A", then get()
|
@@ -168,7 +168,7 @@ public:
|
|
168
168
|
* If left empty, then the app root is used as the app group name.
|
169
169
|
*/
|
170
170
|
StaticString appGroupName;
|
171
|
-
|
171
|
+
|
172
172
|
/** The application's type, used for determining the command to invoke to
|
173
173
|
* spawn an application process as well as determining the startup file's
|
174
174
|
* filename. It can be one of the app type names in AppType.cpp, or the
|
@@ -176,17 +176,17 @@ public:
|
|
176
176
|
* 'startupFile' (which MUST be set) will dictate the startup command
|
177
177
|
* and the startup file's filename. */
|
178
178
|
StaticString appType;
|
179
|
-
|
179
|
+
|
180
180
|
/** The command for spawning the application process. This is a list of
|
181
181
|
* arguments, separated by '\t', e.g. "ruby\tfoo.rb". Only used
|
182
182
|
* during spawning and only if appType.empty(). */
|
183
183
|
StaticString startCommand;
|
184
|
-
|
184
|
+
|
185
185
|
/** Filename of the application's startup file. Only actually used for
|
186
186
|
* determining user switching info. Only used during spawning and only
|
187
187
|
* if appType.empty(). */
|
188
188
|
StaticString startupFile;
|
189
|
-
|
189
|
+
|
190
190
|
/** The process title to assign to the application process. Only used
|
191
191
|
* during spawning. May be empty in which case no particular process
|
192
192
|
* title is assigned. Only used during spawning and only if
|
@@ -197,17 +197,17 @@ public:
|
|
197
197
|
* Defaults to DEFAULT_LOG_LEVEL.
|
198
198
|
*/
|
199
199
|
int logLevel;
|
200
|
-
|
200
|
+
|
201
201
|
/** The maximum amount of time, in milliseconds, that may be spent
|
202
202
|
* on spawning the process or the preloader. */
|
203
203
|
unsigned int startTimeout;
|
204
|
-
|
204
|
+
|
205
205
|
/**
|
206
206
|
* The RAILS_ENV/RACK_ENV environment that should be used. May not be an
|
207
207
|
* empty string.
|
208
208
|
*/
|
209
209
|
StaticString environment;
|
210
|
-
|
210
|
+
|
211
211
|
/**
|
212
212
|
* The base URI on which the application runs. If the application is
|
213
213
|
* running on the root URI, then this value must be "/".
|
@@ -215,12 +215,12 @@ public:
|
|
215
215
|
* @invariant baseURI != ""
|
216
216
|
*/
|
217
217
|
StaticString baseURI;
|
218
|
-
|
218
|
+
|
219
219
|
/**
|
220
220
|
* Spawning method, either "smart" or "direct".
|
221
221
|
*/
|
222
222
|
StaticString spawnMethod;
|
223
|
-
|
223
|
+
|
224
224
|
/** See overview. */
|
225
225
|
StaticString user;
|
226
226
|
/** See class overview. */
|
@@ -229,16 +229,16 @@ public:
|
|
229
229
|
StaticString defaultUser;
|
230
230
|
/** See class overview. Defaults to the defaultUser's primary group. */
|
231
231
|
StaticString defaultGroup;
|
232
|
-
|
232
|
+
|
233
233
|
/**
|
234
234
|
* The directory which contains restart.txt and always_restart.txt.
|
235
235
|
* An empty string means that the default directory should be used.
|
236
236
|
*/
|
237
237
|
StaticString restartDir;
|
238
|
-
|
238
|
+
|
239
239
|
StaticString preexecChroot;
|
240
240
|
StaticString postexecChroot;
|
241
|
-
|
241
|
+
|
242
242
|
/**
|
243
243
|
* Path to the Ruby interpreter to use, in case the application to spawn
|
244
244
|
* is a Ruby app.
|
@@ -256,31 +256,31 @@ public:
|
|
256
256
|
* is a Node.js app.
|
257
257
|
*/
|
258
258
|
StaticString nodejs;
|
259
|
-
|
259
|
+
|
260
260
|
/**
|
261
261
|
* Any rights that the spawned application process may have. The SpawnManager
|
262
262
|
* will create a new account for each spawned app, and that account will be
|
263
263
|
* assigned these rights.
|
264
264
|
*/
|
265
265
|
Account::Rights rights;
|
266
|
-
|
266
|
+
|
267
267
|
/**
|
268
268
|
* Environment variables which should be passed to the spawned application
|
269
269
|
* process.
|
270
270
|
*/
|
271
271
|
vector< pair<StaticString, StaticString> > environmentVariables;
|
272
|
-
|
272
|
+
|
273
273
|
/** Whether debugger support should be enabled. */
|
274
274
|
bool debugger;
|
275
|
-
|
275
|
+
|
276
276
|
/** Whether to load environment variables set in shell startup
|
277
277
|
* files (e.g. ~/.bashrc) during spawning.
|
278
278
|
*/
|
279
279
|
bool loadShellEnvvars;
|
280
|
-
|
280
|
+
|
281
281
|
/** Whether Union Station logging should be enabled. Enabling this option will
|
282
282
|
* result in:
|
283
|
-
*
|
283
|
+
*
|
284
284
|
* - The application enabling its Union Station support.
|
285
285
|
* - Periodic tasks such as `collectAnalytics()` to log things to Union Station.
|
286
286
|
*
|
@@ -300,13 +300,13 @@ public:
|
|
300
300
|
* during unit tests.
|
301
301
|
*/
|
302
302
|
bool raiseInternalError;
|
303
|
-
|
304
|
-
|
303
|
+
|
304
|
+
|
305
305
|
/*********** Per-group pool options that should be set by the caller ***********
|
306
306
|
* These options dictate how Pool will manage processes, routing, etc. within
|
307
307
|
* a single Group. These options are not process-specific, only group-specific.
|
308
308
|
*/
|
309
|
-
|
309
|
+
|
310
310
|
/**
|
311
311
|
* The minimum number of processes for the current group that the application
|
312
312
|
* pool's cleaner thread should keep around.
|
@@ -321,7 +321,7 @@ public:
|
|
321
321
|
* A value of 0 means unspecified, and has no effect.
|
322
322
|
*/
|
323
323
|
unsigned int maxProcesses;
|
324
|
-
|
324
|
+
|
325
325
|
/** The number of seconds that preloader processes may stay alive idling. */
|
326
326
|
long maxPreloaderIdleTime;
|
327
327
|
|
@@ -351,20 +351,20 @@ public:
|
|
351
351
|
StaticString unionStationKey;
|
352
352
|
|
353
353
|
/*-----------------*/
|
354
|
-
|
355
|
-
|
354
|
+
|
355
|
+
|
356
356
|
/*********** Per-request pool options that should be set by the caller ***********
|
357
357
|
* These options also dictate how Pool will manage processes, etc. Unlike the
|
358
358
|
* per-group options, these options are customizable on a per-request basis.
|
359
359
|
* Their effects also don't persist longer than a single request.
|
360
360
|
*/
|
361
|
-
|
361
|
+
|
362
362
|
/** Current request host name. */
|
363
363
|
StaticString hostName;
|
364
|
-
|
364
|
+
|
365
365
|
/** Current request URI. */
|
366
366
|
StaticString uri;
|
367
|
-
|
367
|
+
|
368
368
|
/**
|
369
369
|
* The Union Station log transaction that this request belongs to.
|
370
370
|
* May be the null pointer, in which case Union Station logging is
|
@@ -381,7 +381,7 @@ public:
|
|
381
381
|
* A sticky session ID for routing to a specific process.
|
382
382
|
*/
|
383
383
|
unsigned int stickySessionId;
|
384
|
-
|
384
|
+
|
385
385
|
/**
|
386
386
|
* A throttling rate for file stats. When set to a non-zero value N,
|
387
387
|
* restart.txt and other files which are usually stat()ted on every
|
@@ -408,19 +408,26 @@ public:
|
|
408
408
|
|
409
409
|
/*-----------------*/
|
410
410
|
/*-----------------*/
|
411
|
-
|
412
|
-
|
411
|
+
|
412
|
+
|
413
413
|
/*********** Spawn options automatically set by Pool ***********
|
414
414
|
* These options are passed to the Spawner. The Pool::get() caller may not
|
415
415
|
* see these values.
|
416
416
|
*/
|
417
|
-
|
417
|
+
|
418
418
|
/** The secret key of the pool group that the spawned process is to belong to. */
|
419
419
|
StaticString groupSecret;
|
420
|
-
|
421
|
-
|
420
|
+
|
421
|
+
/**
|
422
|
+
* A UUID that's generated on Group initialization, and changes every time
|
423
|
+
* the Group receives a restart command. Allows Union Station to track app
|
424
|
+
* restarts.
|
425
|
+
*/
|
426
|
+
StaticString groupUuid;
|
427
|
+
|
428
|
+
|
422
429
|
/*********************************/
|
423
|
-
|
430
|
+
|
424
431
|
/**
|
425
432
|
* Creates a new Options object with the default values filled in.
|
426
433
|
* One must still set appRoot manually, after having used this constructor.
|
@@ -428,25 +435,25 @@ public:
|
|
428
435
|
Options() {
|
429
436
|
logLevel = DEFAULT_LOG_LEVEL;
|
430
437
|
startTimeout = 90 * 1000;
|
431
|
-
environment = "production";
|
432
|
-
baseURI = "/";
|
433
|
-
spawnMethod = "smart";
|
434
|
-
defaultUser = "nobody";
|
435
|
-
ruby = DEFAULT_RUBY;
|
436
|
-
python = DEFAULT_PYTHON;
|
437
|
-
nodejs = DEFAULT_NODEJS;
|
438
|
+
environment = P_STATIC_STRING("production");
|
439
|
+
baseURI = P_STATIC_STRING("/");
|
440
|
+
spawnMethod = P_STATIC_STRING("smart");
|
441
|
+
defaultUser = P_STATIC_STRING("nobody");
|
442
|
+
ruby = P_STATIC_STRING(DEFAULT_RUBY);
|
443
|
+
python = P_STATIC_STRING(DEFAULT_PYTHON);
|
444
|
+
nodejs = P_STATIC_STRING(DEFAULT_NODEJS);
|
438
445
|
rights = DEFAULT_BACKEND_ACCOUNT_RIGHTS;
|
439
446
|
debugger = false;
|
440
447
|
loadShellEnvvars = true;
|
441
448
|
analytics = false;
|
442
449
|
raiseInternalError = false;
|
443
|
-
|
450
|
+
|
444
451
|
minProcesses = 1;
|
445
452
|
maxProcesses = 0;
|
446
453
|
maxPreloaderIdleTime = -1;
|
447
454
|
maxOutOfBandWorkInstances = 1;
|
448
455
|
maxRequestQueueSize = 100;
|
449
|
-
|
456
|
+
|
450
457
|
stickySessionId = 0;
|
451
458
|
statThrottleRate = 0;
|
452
459
|
maxRequests = 0;
|
@@ -454,17 +461,17 @@ public:
|
|
454
461
|
|
455
462
|
/*********************************/
|
456
463
|
}
|
457
|
-
|
464
|
+
|
458
465
|
Options copy() const {
|
459
466
|
return *this;
|
460
467
|
}
|
461
|
-
|
468
|
+
|
462
469
|
Options copyAndPersist() const {
|
463
470
|
Options cpy(*this);
|
464
471
|
cpy.persist(*this);
|
465
472
|
return cpy;
|
466
473
|
}
|
467
|
-
|
474
|
+
|
468
475
|
/**
|
469
476
|
* Assign <em>other</em>'s string fields' values into this Option
|
470
477
|
* object, and store the data in this Option object's internal storage
|
@@ -476,9 +483,9 @@ public:
|
|
476
483
|
unsigned int i;
|
477
484
|
size_t otherLen = 0;
|
478
485
|
char *end;
|
479
|
-
|
486
|
+
|
480
487
|
assert(strings.size() == otherStrings.size());
|
481
|
-
|
488
|
+
|
482
489
|
// Calculate the desired length of the internal storage area.
|
483
490
|
// All strings are NULL-terminated.
|
484
491
|
for (i = 0; i < otherStrings.size(); i++) {
|
@@ -488,53 +495,53 @@ public:
|
|
488
495
|
otherLen += environmentVariables[i].first.size() + 1;
|
489
496
|
otherLen += environmentVariables[i].second.size() + 1;
|
490
497
|
}
|
491
|
-
|
498
|
+
|
492
499
|
shared_array<char> data(new char[otherLen]);
|
493
500
|
end = data.get();
|
494
|
-
|
501
|
+
|
495
502
|
// Copy string fields into the internal storage area.
|
496
503
|
for (i = 0; i < otherStrings.size(); i++) {
|
497
504
|
const StaticString *str = strings[i];
|
498
505
|
const StaticString *otherStr = otherStrings[i];
|
499
|
-
|
506
|
+
|
500
507
|
// Point current object's field to the data in the
|
501
508
|
// internal storage area.
|
502
509
|
*const_cast<StaticString *>(str) = StaticString(end, otherStr->size());
|
503
|
-
|
510
|
+
|
504
511
|
// Copy over the string data.
|
505
512
|
memcpy(end, otherStr->c_str(), otherStr->size());
|
506
513
|
end += otherStr->size();
|
507
514
|
*end = '\0';
|
508
515
|
end++;
|
509
516
|
}
|
510
|
-
|
517
|
+
|
511
518
|
// Copy environmentVariables names and values into the internal storage area.
|
512
519
|
for (i = 0; i < other.environmentVariables.size(); i++) {
|
513
520
|
const pair<StaticString, StaticString> &p = other.environmentVariables[i];
|
514
|
-
|
521
|
+
|
515
522
|
environmentVariables[i] = make_pair(
|
516
523
|
StaticString(end, p.first.size()),
|
517
524
|
StaticString(end + p.first.size() + 1, p.second.size())
|
518
525
|
);
|
519
|
-
|
526
|
+
|
520
527
|
// Copy over string data.
|
521
528
|
memcpy(end, p.first.data(), p.first.size());
|
522
529
|
end += p.first.size();
|
523
530
|
*end = '\0';
|
524
531
|
end++;
|
525
|
-
|
532
|
+
|
526
533
|
// Copy over value data.
|
527
534
|
memcpy(end, p.second.data(), p.second.size());
|
528
535
|
end += p.second.size();
|
529
536
|
*end = '\0';
|
530
537
|
end++;
|
531
538
|
}
|
532
|
-
|
539
|
+
|
533
540
|
storage = data;
|
534
|
-
|
541
|
+
|
535
542
|
return *this;
|
536
543
|
}
|
537
|
-
|
544
|
+
|
538
545
|
Options &clearPerRequestFields() {
|
539
546
|
hostName = StaticString();
|
540
547
|
uri = StaticString();
|
@@ -553,7 +560,7 @@ public:
|
|
553
560
|
PER_GROUP_POOL_OPTIONS = 1 << 1,
|
554
561
|
ALL_OPTIONS = ~0
|
555
562
|
};
|
556
|
-
|
563
|
+
|
557
564
|
/**
|
558
565
|
* Append information in this Options object to the given string vector, except
|
559
566
|
* for environmentVariables. You can customize what information you want through
|
@@ -601,7 +608,7 @@ public:
|
|
601
608
|
appendKeyValue3(vec, "max_out_of_band_work_instances", maxOutOfBandWorkInstances);
|
602
609
|
appendKeyValue (vec, "union_station_key", unionStationKey);
|
603
610
|
}
|
604
|
-
|
611
|
+
|
605
612
|
/*********************************/
|
606
613
|
}
|
607
614
|
|
@@ -611,7 +618,7 @@ public:
|
|
611
618
|
{
|
612
619
|
vector<string> args;
|
613
620
|
unsigned int i;
|
614
|
-
|
621
|
+
|
615
622
|
toVector(args, resourceLocator, fields);
|
616
623
|
for (i = 0; i < args.size(); i += 2) {
|
617
624
|
stream << "<" << args[i] << ">";
|
@@ -619,7 +626,7 @@ public:
|
|
619
626
|
stream << "</" << args[i] << ">";
|
620
627
|
}
|
621
628
|
}
|
622
|
-
|
629
|
+
|
623
630
|
/**
|
624
631
|
* Returns the app group name. If there is no explicitly set app group name
|
625
632
|
* then the app root is considered to be the app group name.
|
@@ -631,28 +638,28 @@ public:
|
|
631
638
|
return appGroupName;
|
632
639
|
}
|
633
640
|
}
|
634
|
-
|
641
|
+
|
635
642
|
string getStartCommand(const ResourceLocator &resourceLocator) const {
|
636
|
-
if (appType == "classic-rails") {
|
643
|
+
if (appType == P_STATIC_STRING("classic-rails")) {
|
637
644
|
return ruby + "\t" + resourceLocator.getHelperScriptsDir() + "/classic-rails-loader.rb";
|
638
|
-
} else if (appType == "rack") {
|
645
|
+
} else if (appType == P_STATIC_STRING("rack")) {
|
639
646
|
return ruby + "\t" + resourceLocator.getHelperScriptsDir() + "/rack-loader.rb";
|
640
|
-
} else if (appType == "wsgi") {
|
647
|
+
} else if (appType == P_STATIC_STRING("wsgi")) {
|
641
648
|
return python + "\t" + resourceLocator.getHelperScriptsDir() + "/wsgi-loader.py";
|
642
|
-
} else if (appType == "node") {
|
649
|
+
} else if (appType == P_STATIC_STRING("node")) {
|
643
650
|
return nodejs + "\t" + resourceLocator.getHelperScriptsDir() + "/node-loader.js";
|
644
|
-
} else if (appType == "meteor") {
|
651
|
+
} else if (appType == P_STATIC_STRING("meteor")) {
|
645
652
|
return ruby + "\t" + resourceLocator.getHelperScriptsDir() + "/meteor-loader.rb";
|
646
653
|
} else {
|
647
654
|
return startCommand;
|
648
655
|
}
|
649
656
|
}
|
650
|
-
|
657
|
+
|
651
658
|
StaticString getStartupFile() const {
|
652
659
|
if (startupFile.empty()) {
|
653
660
|
const char *result = getAppTypeStartupFile(getAppType(appType));
|
654
661
|
if (result == NULL) {
|
655
|
-
return "";
|
662
|
+
return P_STATIC_STRING("");
|
656
663
|
} else {
|
657
664
|
return result;
|
658
665
|
}
|
@@ -660,7 +667,7 @@ public:
|
|
660
667
|
return startupFile;
|
661
668
|
}
|
662
669
|
}
|
663
|
-
|
670
|
+
|
664
671
|
StaticString getProcessTitle() const {
|
665
672
|
const char *result = getAppTypeProcessTitle(getAppType(appType));
|
666
673
|
if (result == NULL) {
|
@@ -669,7 +676,7 @@ public:
|
|
669
676
|
return result;
|
670
677
|
}
|
671
678
|
}
|
672
|
-
|
679
|
+
|
673
680
|
unsigned long getMaxPreloaderIdleTime() const {
|
674
681
|
if (maxPreloaderIdleTime == -1) {
|
675
682
|
return 5 * 60;
|