passenger 5.1.7 → 5.1.8
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 +4 -4
- data/CHANGELOG +13 -2
- data/CONTRIBUTING.md +1 -1
- data/build/agent.rb +1 -1
- data/build/cxx_tests.rb +6 -0
- data/build/support/cxx_dependency_map.rb +1286 -391
- data/build/support/general.rb +0 -26
- data/resources/templates/standalone/rails_asset_pipeline.erb +2 -2
- data/src/agent/Core/ApiServer.h +49 -44
- data/src/agent/Core/ApplicationPool/Pool.h +1 -1
- data/src/agent/Core/ApplicationPool/Process.h +1 -1
- data/src/agent/Core/ApplicationPool/Socket.h +1 -1
- data/src/agent/Core/Controller.h +16 -8
- data/src/agent/Core/Controller/CheckoutSession.cpp +1 -1
- data/src/agent/Core/Controller/Config.cpp +68 -0
- data/src/agent/Core/Controller/Config.h +70 -34
- data/src/agent/Core/Controller/ForwardResponse.cpp +5 -5
- data/src/agent/Core/Controller/Hooks.cpp +5 -14
- data/src/agent/Core/Controller/Implementation.cpp +1 -1
- data/src/agent/Core/Controller/InitRequest.cpp +31 -29
- data/src/agent/Core/Controller/InitializationAndShutdown.cpp +4 -4
- data/src/agent/Core/Controller/InternalUtils.cpp +3 -3
- data/src/agent/Core/Controller/Miscellaneous.cpp +1 -1
- data/src/agent/Core/Controller/Request.h +2 -2
- data/src/agent/Core/Controller/SendRequest.cpp +5 -5
- data/src/agent/Core/Controller/StateInspection.cpp +1 -1
- data/src/agent/Core/Controller/TurboCaching.h +2 -2
- data/src/agent/Core/CoreMain.cpp +2 -2
- data/src/agent/Core/ResponseCache.h +3 -3
- data/src/agent/Core/SpawningKit/BackgroundIOCapturer.h +3 -3
- data/src/agent/Core/SpawningKit/DirectSpawner.h +2 -2
- data/src/agent/Core/SpawningKit/PipeWatcher.h +3 -3
- data/src/agent/Core/SpawningKit/SmartSpawner.h +2 -2
- data/src/agent/Core/SpawningKit/Spawner.h +1 -1
- data/src/agent/Core/UnionStation/Connection.h +1 -1
- data/src/agent/Core/UnionStation/Context.h +1 -1
- data/src/agent/Core/UnionStation/Transaction.h +1 -1
- data/src/agent/Shared/ApiServerUtils.h +73 -27
- data/src/agent/Shared/Base.cpp +61 -73
- data/src/agent/UstRouter/ApiServer.h +34 -45
- data/src/agent/UstRouter/Controller.h +86 -60
- data/src/agent/UstRouter/RemoteSender.h +1 -1
- data/src/agent/UstRouter/RemoteSink.h +1 -1
- data/src/agent/Watchdog/ApiServer.h +42 -50
- data/src/agent/Watchdog/WatchdogMain.cpp +1 -1
- data/src/apache2_module/Configuration.hpp +1 -1
- data/src/apache2_module/Hooks.cpp +27 -13
- data/src/cxx_supportlib/AppTypes.h +1 -1
- data/src/cxx_supportlib/BackgroundEventLoop.cpp +1 -1
- data/src/cxx_supportlib/ConfigKit/AsyncUtils.h +86 -0
- data/src/cxx_supportlib/ConfigKit/Common.h +6 -3
- data/src/cxx_supportlib/ConfigKit/IN_PRACTICE.md +1039 -0
- data/src/cxx_supportlib/ConfigKit/README.md +112 -497
- data/src/cxx_supportlib/ConfigKit/Schema.h +78 -15
- data/src/cxx_supportlib/ConfigKit/Store.h +272 -53
- data/src/cxx_supportlib/ConfigKit/SubComponentUtils.h +59 -0
- data/src/cxx_supportlib/ConfigKit/Utils.h +26 -65
- data/src/cxx_supportlib/ConfigKit/ValidationUtils.h +69 -0
- data/src/cxx_supportlib/ConfigKit/VariantMapUtils.h +7 -4
- data/src/cxx_supportlib/Constants.h +4 -1
- data/src/cxx_supportlib/Crypto.cpp +1 -1
- data/src/cxx_supportlib/DataStructures/StringKeyTable.h +26 -7
- data/src/cxx_supportlib/FileDescriptor.h +1 -1
- data/src/cxx_supportlib/Hooks.h +1 -1
- data/src/cxx_supportlib/LoggingKit/Assert.h +130 -0
- data/src/cxx_supportlib/LoggingKit/Config.h +97 -0
- data/src/cxx_supportlib/LoggingKit/Context.h +94 -0
- data/src/cxx_supportlib/LoggingKit/Forward.h +95 -0
- data/src/cxx_supportlib/LoggingKit/Implementation.cpp +695 -0
- data/src/cxx_supportlib/LoggingKit/Logging.h +204 -0
- data/src/cxx_supportlib/LoggingKit/LoggingKit.h +33 -0
- data/src/cxx_supportlib/LveLoggingDecorator.h +1 -1
- data/src/cxx_supportlib/MemoryKit/mbuf.cpp +1 -1
- data/src/cxx_supportlib/RandomGenerator.h +1 -1
- data/src/cxx_supportlib/SafeLibev.h +1 -1
- data/src/cxx_supportlib/ServerKit/AcceptLoadBalancer.h +1 -1
- data/src/cxx_supportlib/ServerKit/Channel.h +1 -1
- data/src/cxx_supportlib/ServerKit/FileBufferedChannel.h +1 -1
- data/src/cxx_supportlib/ServerKit/FileBufferedFdSinkChannel.h +1 -1
- data/src/cxx_supportlib/ServerKit/HttpChunkedBodyParser.h +1 -1
- data/src/cxx_supportlib/ServerKit/HttpHeaderParser.h +1 -1
- data/src/cxx_supportlib/ServerKit/HttpServer.h +48 -15
- data/src/cxx_supportlib/ServerKit/Server.h +79 -52
- data/src/cxx_supportlib/StaticString.h +12 -0
- data/src/cxx_supportlib/Utils/Curl.h +16 -0
- data/src/cxx_supportlib/Utils/FastStringStream.h +6 -1
- data/src/cxx_supportlib/Utils/ScopeGuard.h +1 -1
- data/src/cxx_supportlib/Utils/StrIntUtils.cpp +2 -19
- data/src/cxx_supportlib/WatchdogLauncher.h +3 -2
- data/src/ruby_supportlib/phusion_passenger.rb +3 -3
- data/src/ruby_supportlib/phusion_passenger/common_library.rb +12 -12
- data/src/ruby_supportlib/phusion_passenger/constants.rb +6 -3
- data/src/ruby_supportlib/phusion_passenger/standalone/start_command.rb +1 -0
- data/src/ruby_supportlib/phusion_passenger/standalone/stop_command.rb +1 -0
- metadata +14 -4
- data/src/cxx_supportlib/Logging.cpp +0 -295
- data/src/cxx_supportlib/Logging.h +0 -385
data/build/support/general.rb
CHANGED
@@ -22,32 +22,6 @@
|
|
22
22
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23
23
|
# THE SOFTWARE.
|
24
24
|
|
25
|
-
class TemplateRenderer
|
26
|
-
def initialize(filename)
|
27
|
-
require 'erb' if !defined?(ERB)
|
28
|
-
@erb = ERB.new(File.read(filename), nil, "-")
|
29
|
-
@erb.filename = filename
|
30
|
-
end
|
31
|
-
|
32
|
-
def render
|
33
|
-
return @erb.result(binding)
|
34
|
-
end
|
35
|
-
|
36
|
-
def render_to(filename)
|
37
|
-
puts "Creating #{filename}"
|
38
|
-
text = render
|
39
|
-
# When packaging, some timestamps may be modified. The user may not
|
40
|
-
# have write access to the source root (for example, when Passenger
|
41
|
-
# Standalone is compiling its runtime), so we only write to the file
|
42
|
-
# when necessary.
|
43
|
-
if !File.exist?(filename) || File.writable?(filename) || File.read(filename) != text
|
44
|
-
File.open(filename, 'w') do |f|
|
45
|
-
f.write(text)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
25
|
class CxxCodeTemplateRenderer
|
52
26
|
def initialize(filename)
|
53
27
|
if !defined?(CxxCodeBuilder)
|
@@ -1,5 +1,5 @@
|
|
1
|
-
# Rails asset pipeline support.
|
2
|
-
location ~ "^/assets/.+-([0-9a-f]{32}|[0-9a-f]{64})\..+" {
|
1
|
+
# Rails asset pipeline & webpacker support.
|
2
|
+
location ~ "^/(assets|packs)/.+-([0-9a-f]{32}|[0-9a-f]{64}|[0-9a-f]{20})\..+" {
|
3
3
|
error_page 490 = @static_asset;
|
4
4
|
error_page 491 = @dynamic_request;
|
5
5
|
recursive_error_pages on;
|
data/src/agent/Core/ApiServer.h
CHANGED
@@ -28,9 +28,9 @@
|
|
28
28
|
|
29
29
|
#include <boost/regex.hpp>
|
30
30
|
#include <oxt/thread.hpp>
|
31
|
-
#include <sstream>
|
32
31
|
#include <string>
|
33
32
|
#include <cstring>
|
33
|
+
#include <exception>
|
34
34
|
#include <sys/types.h>
|
35
35
|
|
36
36
|
#include <jsoncpp/json.h>
|
@@ -43,7 +43,8 @@
|
|
43
43
|
#include <DataStructures/LString.h>
|
44
44
|
#include <Exceptions.h>
|
45
45
|
#include <StaticString.h>
|
46
|
-
#include <
|
46
|
+
#include <LoggingKit/LoggingKit.h>
|
47
|
+
#include <LoggingKit/Context.h>
|
47
48
|
#include <Constants.h>
|
48
49
|
#include <Utils/StrIntUtils.h>
|
49
50
|
#include <Utils/BufferedIO.h>
|
@@ -413,7 +414,7 @@ private:
|
|
413
414
|
count = mbuf_pool_compact(&ctx->mbuf_pool);
|
414
415
|
SKS_NOTICE_FROM_STATIC(controller, "Freed " << count << " mbufs");
|
415
416
|
|
416
|
-
controller->compact(
|
417
|
+
controller->compact(LoggingKit::NOTICE);
|
417
418
|
}
|
418
419
|
|
419
420
|
void processGc(Client *client, Request *req) {
|
@@ -475,16 +476,18 @@ private:
|
|
475
476
|
}
|
476
477
|
|
477
478
|
HeaderTable headers;
|
478
|
-
|
479
|
-
string fileDescriptorLogFile = getFileDescriptorLogFile();
|
479
|
+
ConfigKit::Store loggingConfig = LoggingKit::context->getConfig();
|
480
480
|
|
481
481
|
headers.insert(req->pool, "Content-Type", "application/json");
|
482
|
-
config["log_level"] =
|
483
|
-
if (
|
484
|
-
config["log_file"] =
|
482
|
+
config["log_level"] = (int) LoggingKit::parseLevel(loggingConfig["level"].asString());
|
483
|
+
if (loggingConfig["target"].isMember("path")) {
|
484
|
+
config["log_file"] = loggingConfig["target"]["path"].asString();
|
485
485
|
}
|
486
|
-
if (!
|
487
|
-
|
486
|
+
if (!loggingConfig["file_descriptor_log_target"].isNull()
|
487
|
+
&& loggingConfig["file_descriptor_log_target"].isMember("path"))
|
488
|
+
{
|
489
|
+
config["file_descriptor_log_file"] =
|
490
|
+
loggingConfig["file_descriptor_log_target"]["path"].asString();
|
488
491
|
}
|
489
492
|
|
490
493
|
writeSimpleResponse(client, 200, &headers,
|
@@ -499,7 +502,11 @@ private:
|
|
499
502
|
|
500
503
|
static void configureController(Controller *controller, Json::Value updates) {
|
501
504
|
vector<ConfigKit::Error> errors;
|
502
|
-
|
505
|
+
ControllerConfigChangeRequest req;
|
506
|
+
|
507
|
+
if (controller->prepareConfigChange(updates, errors, req)) {
|
508
|
+
controller->commitConfigChange(req);
|
509
|
+
} else {
|
503
510
|
P_ERROR("Unable to apply configuration change to Core controller.\n"
|
504
511
|
"Configuration: " << updates.toStyledString() << "\n"
|
505
512
|
"Errors: " << toString(errors));
|
@@ -508,46 +515,44 @@ private:
|
|
508
515
|
|
509
516
|
void processConfigBody(Client *client, Request *req) {
|
510
517
|
HeaderTable headers;
|
511
|
-
|
518
|
+
LoggingKit::ConfigChangeRequest configReq;
|
519
|
+
const Json::Value &json = req->jsonBody;
|
520
|
+
vector<ConfigKit::Error> errors;
|
521
|
+
bool ok;
|
512
522
|
|
513
523
|
headers.insert(req->pool, "Content-Type", "application/json");
|
514
524
|
headers.insert(req->pool, "Cache-Control", "no-cache, no-store, must-revalidate");
|
515
525
|
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
e.what());
|
529
|
-
writeSimpleResponse(client, 500, &headers, message);
|
530
|
-
if (!req->ended()) {
|
531
|
-
endRequest(&client, &req);
|
532
|
-
}
|
533
|
-
return;
|
526
|
+
try {
|
527
|
+
ok = LoggingKit::context->prepareConfigChange(json,
|
528
|
+
errors, configReq);
|
529
|
+
} catch (const std::exception &e) {
|
530
|
+
unsigned int bufsize = 2048;
|
531
|
+
char *message = (char *) psg_pnalloc(req->pool, bufsize);
|
532
|
+
snprintf(message, bufsize, "{ \"status\": \"error\", "
|
533
|
+
"\"message\": \"Error reconfiguring logging system: %s\" }",
|
534
|
+
e.what());
|
535
|
+
writeSimpleResponse(client, 500, &headers, message);
|
536
|
+
if (!req->ended()) {
|
537
|
+
endRequest(&client, &req);
|
534
538
|
}
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
}
|
547
|
-
return;
|
539
|
+
return;
|
540
|
+
}
|
541
|
+
if (!ok) {
|
542
|
+
unsigned int bufsize = 2048;
|
543
|
+
char *message = (char *) psg_pnalloc(req->pool, bufsize);
|
544
|
+
snprintf(message, bufsize, "{ \"status\": \"error\", "
|
545
|
+
"\"message\": \"Error reconfiguring logging system: %s\" }",
|
546
|
+
ConfigKit::toString(errors).c_str());
|
547
|
+
writeSimpleResponse(client, 500, &headers, message);
|
548
|
+
if (!req->ended()) {
|
549
|
+
endRequest(&client, &req);
|
548
550
|
}
|
549
|
-
|
551
|
+
return;
|
550
552
|
}
|
553
|
+
|
554
|
+
LoggingKit::context->commitConfigChange(configReq);
|
555
|
+
|
551
556
|
for (unsigned int i = 0; i < controllers.size(); i++) {
|
552
557
|
controllers[i]->getContext()->libev->runLater(boost::bind(
|
553
558
|
configureController, controllers[i], json));
|
data/src/agent/Core/Controller.h
CHANGED
@@ -32,7 +32,7 @@
|
|
32
32
|
|
33
33
|
#define CC_BENCHMARK_POINT(client, req, value) \
|
34
34
|
do { \
|
35
|
-
if (OXT_UNLIKELY(
|
35
|
+
if (OXT_UNLIKELY(mainConfig.benchmarkMode == value)) { \
|
36
36
|
writeBenchmarkResponse(&client, &req); \
|
37
37
|
return; \
|
38
38
|
} \
|
@@ -61,7 +61,7 @@
|
|
61
61
|
#include <cassert>
|
62
62
|
#include <cctype>
|
63
63
|
|
64
|
-
#include <
|
64
|
+
#include <LoggingKit/LoggingKit.h>
|
65
65
|
#include <MessageReadersWriters.h>
|
66
66
|
#include <Constants.h>
|
67
67
|
#include <ConfigKit/ConfigKit.h>
|
@@ -109,13 +109,14 @@ private:
|
|
109
109
|
typedef ServerKit::FdSourceChannel FdSourceChannel;
|
110
110
|
typedef ServerKit::FileBufferedChannel FileBufferedChannel;
|
111
111
|
typedef ServerKit::FileBufferedFdSinkChannel FileBufferedFdSinkChannel;
|
112
|
+
typedef ControllerConfigChangeRequest ConfigChangeRequest;
|
112
113
|
|
113
114
|
// If you change this value, make sure that Request::sessionCheckoutTry
|
114
115
|
// has enough bits.
|
115
116
|
static const unsigned int MAX_SESSION_CHECKOUT_TRY = 10;
|
116
117
|
|
117
|
-
|
118
|
-
|
118
|
+
ControllerMainConfig mainConfig;
|
119
|
+
ControllerRequestConfigPtr requestConfig;
|
119
120
|
StringKeyTable< boost::shared_ptr<Options> > poolOptionsCache;
|
120
121
|
|
121
122
|
HashedStaticString PASSENGER_APP_GROUP_NAME;
|
@@ -158,8 +159,8 @@ private:
|
|
158
159
|
void initializeFlags(Client *client, Request *req, RequestAnalysis &analysis);
|
159
160
|
bool respondFromTurboCache(Client *client, Request *req);
|
160
161
|
void initializePoolOptions(Client *client, Request *req, RequestAnalysis &analysis);
|
161
|
-
void fillPoolOptionsFromConfigCaches(Options &options,
|
162
|
-
const
|
162
|
+
void fillPoolOptionsFromConfigCaches(Options &options, psg_pool_t *pool,
|
163
|
+
const ControllerRequestConfigPtr &requestConfigCache);
|
163
164
|
static void fillPoolOption(Request *req, StaticString &field,
|
164
165
|
const HashedStaticString &name);
|
165
166
|
static void fillPoolOption(Request *req, int &field,
|
@@ -350,7 +351,6 @@ protected:
|
|
350
351
|
virtual void onNextRequestEarlyReadError(Client *client, Request *req, int errcode);
|
351
352
|
virtual bool shouldDisconnectClientOnShutdown(Client *client);
|
352
353
|
virtual bool supportsUpgrade(Client *client, Request *req);
|
353
|
-
virtual void onConfigChange(const ConfigKit::Store *oldConfig);
|
354
354
|
|
355
355
|
|
356
356
|
/****** Marked virtual so that unit tests can mock these ******/
|
@@ -380,7 +380,15 @@ public:
|
|
380
380
|
virtual StaticString getServerName() const;
|
381
381
|
|
382
382
|
|
383
|
-
/******
|
383
|
+
/****** Configuration handling ******/
|
384
|
+
|
385
|
+
bool prepareConfigChange(const Json::Value &updates,
|
386
|
+
vector<ConfigKit::Error> &errors, ControllerConfigChangeRequest &req);
|
387
|
+
void commitConfigChange(ControllerConfigChangeRequest &req)
|
388
|
+
BOOST_NOEXCEPT_OR_NOTHROW;
|
389
|
+
|
390
|
+
|
391
|
+
/****** State and configuration ******/
|
384
392
|
|
385
393
|
unsigned int getThreadNumber() const; // Thread-safe
|
386
394
|
virtual Json::Value inspectStateAsJson() const;
|
@@ -377,7 +377,7 @@ Controller::endRequestWithErrorResponse(Client **c, Request **r, const StaticStr
|
|
377
377
|
bool
|
378
378
|
Controller::friendlyErrorPagesEnabled(Request *req) {
|
379
379
|
bool defaultValue;
|
380
|
-
const StaticString &defaultStr = req->
|
380
|
+
const StaticString &defaultStr = req->config->friendlyErrorPages;
|
381
381
|
if (defaultStr == "auto") {
|
382
382
|
defaultValue = (req->options.environment == "development");
|
383
383
|
} else {
|
@@ -0,0 +1,68 @@
|
|
1
|
+
/*
|
2
|
+
* Phusion Passenger - https://www.phusionpassenger.com/
|
3
|
+
* Copyright (c) 2017 Phusion Holding B.V.
|
4
|
+
*
|
5
|
+
* "Passenger", "Phusion Passenger" and "Union Station" are registered
|
6
|
+
* trademarks of Phusion Holding B.V.
|
7
|
+
*
|
8
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
9
|
+
* of this software and associated documentation files (the "Software"), to deal
|
10
|
+
* in the Software without restriction, including without limitation the rights
|
11
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
12
|
+
* copies of the Software, and to permit persons to whom the Software is
|
13
|
+
* furnished to do so, subject to the following conditions:
|
14
|
+
*
|
15
|
+
* The above copyright notice and this permission notice shall be included in
|
16
|
+
* all copies or substantial portions of the Software.
|
17
|
+
*
|
18
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
19
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
20
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
21
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
22
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
23
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
24
|
+
* THE SOFTWARE.
|
25
|
+
*/
|
26
|
+
#include <Core/Controller.h>
|
27
|
+
|
28
|
+
namespace Passenger {
|
29
|
+
namespace Core {
|
30
|
+
|
31
|
+
using namespace std;
|
32
|
+
|
33
|
+
|
34
|
+
/****************************
|
35
|
+
*
|
36
|
+
* Private methods
|
37
|
+
*
|
38
|
+
****************************/
|
39
|
+
|
40
|
+
|
41
|
+
bool
|
42
|
+
Controller::prepareConfigChange(const Json::Value &updates,
|
43
|
+
vector<ConfigKit::Error> &errors,
|
44
|
+
ControllerConfigChangeRequest &req)
|
45
|
+
{
|
46
|
+
if (ParentClass::prepareConfigChange(updates, errors, req.forParent)) {
|
47
|
+
req.mainConfig.reset(new ControllerMainConfig(
|
48
|
+
*req.forParent.forParent.config));
|
49
|
+
req.requestConfig.reset(new ControllerRequestConfig(
|
50
|
+
*req.forParent.forParent.config));
|
51
|
+
}
|
52
|
+
return errors.empty();
|
53
|
+
}
|
54
|
+
|
55
|
+
void
|
56
|
+
Controller::commitConfigChange(ControllerConfigChangeRequest &req)
|
57
|
+
BOOST_NOEXCEPT_OR_NOTHROW
|
58
|
+
{
|
59
|
+
ParentClass::commitConfigChange(req.forParent);
|
60
|
+
mainConfig.swap(*req.mainConfig);
|
61
|
+
requestConfig.swap(req.requestConfig);
|
62
|
+
getContext()->defaultFileBufferedChannelConfig.bufferDir =
|
63
|
+
config["data_buffer_dir"].asString();
|
64
|
+
}
|
65
|
+
|
66
|
+
|
67
|
+
} // namespace Core
|
68
|
+
} // namespace Passenger
|
@@ -31,6 +31,7 @@
|
|
31
31
|
#include <string.h>
|
32
32
|
|
33
33
|
#include <ConfigKit/ConfigKit.h>
|
34
|
+
#include <ConfigKit/ValidationUtils.h>
|
34
35
|
#include <MemoryKit/palloc.h>
|
35
36
|
#include <ServerKit/HttpServer.h>
|
36
37
|
#include <Constants.h>
|
@@ -113,6 +114,7 @@ private:
|
|
113
114
|
add("force_max_concurrent_requests_per_process", INT_TYPE, OPTIONAL, -1);
|
114
115
|
add("abort_websockets_on_process_shutdown", BOOL_TYPE, OPTIONAL, true);
|
115
116
|
add("load_shell_envvars", BOOL_TYPE, OPTIONAL, false);
|
117
|
+
add("max_requests", UINT_TYPE, OPTIONAL, 0);
|
116
118
|
|
117
119
|
// Single app mode options
|
118
120
|
add("app_root", STRING_TYPE, OPTIONAL);
|
@@ -128,6 +130,7 @@ private:
|
|
128
130
|
addValidator(validate);
|
129
131
|
addValidator(validateMultiAppMode);
|
130
132
|
addValidator(validateSingleAppMode);
|
133
|
+
addValidator(ConfigKit::validateIntegrationMode);
|
131
134
|
}
|
132
135
|
|
133
136
|
static Json::Value inferDefaultValueForDefaultGroup(const ConfigKit::Store &config) {
|
@@ -177,15 +180,15 @@ private:
|
|
177
180
|
}
|
178
181
|
|
179
182
|
if (config["app_root"].isNull()) {
|
180
|
-
errors.push_back(Error("If '{{multi_app}}' is set"
|
183
|
+
errors.push_back(Error("If '{{multi_app}}' is not set"
|
181
184
|
" then '{{app_root}}' is required"));
|
182
185
|
}
|
183
186
|
if (config["app_type"].isNull()) {
|
184
|
-
errors.push_back(Error("If '{{multi_app}}' is set"
|
187
|
+
errors.push_back(Error("If '{{multi_app}}' is not set"
|
185
188
|
" then '{{app_type}}' is required"));
|
186
189
|
}
|
187
190
|
if (config["startup_file"].isNull()) {
|
188
|
-
errors.push_back(Error("If '{{multi_app}}' is set"
|
191
|
+
errors.push_back(Error("If '{{multi_app}}' is not set"
|
189
192
|
" then '{{startup_file}}' is required"));
|
190
193
|
}
|
191
194
|
|
@@ -228,7 +231,17 @@ public:
|
|
228
231
|
}
|
229
232
|
};
|
230
233
|
|
231
|
-
|
234
|
+
/**
|
235
|
+
* A structure that caches controller configuration which is allowed to
|
236
|
+
* change at any time, even during the middle of a request.
|
237
|
+
*/
|
238
|
+
class ControllerMainConfig {
|
239
|
+
private:
|
240
|
+
StaticString createServerLogName() {
|
241
|
+
string name = "ServerThr." + toString(threadNumber);
|
242
|
+
return psg_pstrdup(pool, name);
|
243
|
+
}
|
244
|
+
|
232
245
|
public:
|
233
246
|
psg_pool_t *pool;
|
234
247
|
|
@@ -245,49 +258,63 @@ public:
|
|
245
258
|
/*******************/
|
246
259
|
/*******************/
|
247
260
|
|
248
|
-
|
261
|
+
ControllerMainConfig(const ConfigKit::Store &config)
|
249
262
|
: pool(psg_create_pool(1024)),
|
250
263
|
|
251
|
-
threadNumber(
|
252
|
-
statThrottleRate(
|
253
|
-
responseBufferHighWatermark(
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
264
|
+
threadNumber(config["thread_number"].asUInt()),
|
265
|
+
statThrottleRate(config["stat_throttle_rate"].asUInt()),
|
266
|
+
responseBufferHighWatermark(config["response_buffer_high_watermark"].asUInt()),
|
267
|
+
integrationMode(psg_pstrdup(pool, config["integration_mode"].asString())),
|
268
|
+
serverLogName(createServerLogName()),
|
269
|
+
benchmarkMode(parseControllerBenchmarkMode(config["benchmark_mode"].asString())),
|
270
|
+
userSwitching(config["user_switching"].asBool()),
|
271
|
+
stickySessions(config["sticky_sessions"].asBool()),
|
272
|
+
gracefulExit(config["core_graceful_exit"].asBool())
|
258
273
|
|
259
274
|
/*******************/
|
260
275
|
{
|
261
|
-
update(initialConfig);
|
262
|
-
|
263
|
-
integrationMode = psg_pstrdup(pool, initialConfig["integration_mode"].asString());
|
264
|
-
|
265
|
-
string name = "ServerThr." + toString(threadNumber);
|
266
|
-
serverLogName = psg_pstrdup(pool, name);
|
267
|
-
|
268
276
|
/*******************/
|
269
277
|
}
|
270
278
|
|
271
|
-
~
|
279
|
+
~ControllerMainConfig() {
|
272
280
|
psg_destroy_pool(pool);
|
273
281
|
}
|
274
282
|
|
275
|
-
void
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
283
|
+
void swap(ControllerMainConfig &other) BOOST_NOEXCEPT_OR_NOTHROW {
|
284
|
+
#define SWAP_BITFIELD(Type, name) \
|
285
|
+
do { \
|
286
|
+
Type tmp = name; \
|
287
|
+
name = other.name; \
|
288
|
+
other.name = tmp; \
|
289
|
+
} while (false)
|
290
|
+
|
291
|
+
std::swap(pool, other.pool);
|
292
|
+
std::swap(threadNumber, other.threadNumber);
|
293
|
+
std::swap(statThrottleRate, other.statThrottleRate);
|
294
|
+
std::swap(responseBufferHighWatermark, other.responseBufferHighWatermark);
|
295
|
+
std::swap(integrationMode, other.integrationMode);
|
296
|
+
std::swap(serverLogName, other.serverLogName);
|
297
|
+
SWAP_BITFIELD(ControllerBenchmarkMode, benchmarkMode);
|
298
|
+
SWAP_BITFIELD(bool, userSwitching);
|
299
|
+
SWAP_BITFIELD(bool, stickySessions);
|
300
|
+
SWAP_BITFIELD(bool, gracefulExit);
|
284
301
|
|
285
302
|
/*******************/
|
303
|
+
|
304
|
+
#undef SWAP_BITFIELD
|
286
305
|
}
|
287
306
|
};
|
288
307
|
|
289
|
-
|
290
|
-
|
308
|
+
/**
|
309
|
+
* A structure that caches controller configuration that must stay the
|
310
|
+
* same for the entire duration of a request.
|
311
|
+
*
|
312
|
+
* Note that this structure has got nothing to do with per-request config
|
313
|
+
* options: options which may be configured by the web server on a
|
314
|
+
* per-request basis. That is an orthogonal concept.
|
315
|
+
*/
|
316
|
+
class ControllerRequestConfig:
|
317
|
+
public boost::intrusive_ref_counter<ControllerRequestConfig,
|
291
318
|
boost::thread_unsafe_counter>
|
292
319
|
{
|
293
320
|
public:
|
@@ -313,6 +340,7 @@ public:
|
|
313
340
|
unsigned int minInstances;
|
314
341
|
unsigned int maxPreloaderIdleTime;
|
315
342
|
unsigned int maxRequestQueueSize;
|
343
|
+
unsigned int maxRequests;
|
316
344
|
int forceMaxConcurrentRequestsPerProcess;
|
317
345
|
bool singleAppMode: 1;
|
318
346
|
bool showVersionInHeader: 1;
|
@@ -323,7 +351,7 @@ public:
|
|
323
351
|
/*******************/
|
324
352
|
|
325
353
|
|
326
|
-
|
354
|
+
ControllerRequestConfig(const ConfigKit::Store &config)
|
327
355
|
: pool(psg_create_pool(1024 * 4)),
|
328
356
|
|
329
357
|
defaultRuby(psg_pstrdup(pool, config["default_ruby"].asString())),
|
@@ -346,6 +374,7 @@ public:
|
|
346
374
|
minInstances(config["min_instances"].asUInt()),
|
347
375
|
maxPreloaderIdleTime(config["max_preloader_idle_time"].asUInt()),
|
348
376
|
maxRequestQueueSize(config["max_request_queue_size"].asUInt()),
|
377
|
+
maxRequests(config["max_requests"].asUInt()),
|
349
378
|
forceMaxConcurrentRequestsPerProcess(config["force_max_concurrent_requests_per_process"].asInt()),
|
350
379
|
singleAppMode(!config["multi_app"].asBool()),
|
351
380
|
showVersionInHeader(config["show_version_in_header"].asBool()),
|
@@ -355,12 +384,19 @@ public:
|
|
355
384
|
/*******************/
|
356
385
|
{ }
|
357
386
|
|
358
|
-
~
|
387
|
+
~ControllerRequestConfig() {
|
359
388
|
psg_destroy_pool(pool);
|
360
389
|
}
|
361
390
|
};
|
362
391
|
|
363
|
-
typedef boost::intrusive_ptr<
|
392
|
+
typedef boost::intrusive_ptr<ControllerRequestConfig> ControllerRequestConfigPtr;
|
393
|
+
|
394
|
+
|
395
|
+
struct ControllerConfigChangeRequest {
|
396
|
+
ServerKit::HttpServerConfigChangeRequest forParent;
|
397
|
+
boost::scoped_ptr<ControllerMainConfig> mainConfig;
|
398
|
+
ControllerRequestConfigPtr requestConfig;
|
399
|
+
};
|
364
400
|
|
365
401
|
|
366
402
|
} // namespace Core
|