passenger 3.0.6 → 3.0.7
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of passenger might be problematic. Click here for more details.
- data/NEWS +21 -0
- data/build/agents.rb +0 -1
- data/build/cxx_tests.rb +0 -1
- data/doc/Users guide Apache.html +1 -1
- data/doc/cxxapi/Constants_8h_source.html +1 -1
- data/doc/cxxapi/StaticContentHandler_8h_source.html +8 -7
- data/doc/cxxapi/graph_legend.png +0 -0
- data/doc/cxxapi/group__Core.html +1 -1
- data/doc/cxxapi/group__Core.map +1 -1
- data/doc/cxxapi/group__Core.png +0 -0
- data/doc/cxxapi/group__Hooks.html +1 -1
- data/doc/cxxapi/group__Hooks.map +1 -1
- data/doc/cxxapi/group__Hooks.png +0 -0
- data/doc/cxxapi/ngx__http__passenger__module_8h_source.html +34 -33
- data/ext/apache2/Hooks.cpp +1 -0
- data/ext/common/AgentBase.cpp +6 -2
- data/ext/common/Constants.h +1 -1
- data/ext/common/LoggingAgent/LoggingServer.h +13 -166
- data/ext/common/LoggingAgent/RemoteSender.h +9 -1
- data/ext/common/Utils/BlockingQueue.h +20 -1
- data/ext/common/Watchdog.cpp +58 -17
- data/ext/nginx/HelperAgent.cpp +9 -2
- data/ext/nginx/StaticContentHandler.h +1 -0
- data/ext/nginx/ngx_http_passenger_module.h +1 -0
- data/lib/phusion_passenger.rb +3 -3
- data/lib/phusion_passenger/platform_info/apache.rb +1 -1
- data/lib/phusion_passenger/standalone/start_command.rb +0 -11
- data/lib/phusion_passenger/templates/standalone/config.erb +1 -0
- data/test/cxx/LoggingTest.cpp +2 -161
- metadata +4 -5
- data/ext/common/LoggingAgent/ChangeNotifier.h +0 -63
data/NEWS
CHANGED
@@ -1,3 +1,24 @@
|
|
1
|
+
Release 3.0.7
|
2
|
+
-------------
|
3
|
+
|
4
|
+
* Fixed a bug passenger-install-apache2-module. It could crash on
|
5
|
+
some systems due to a typo in the code.
|
6
|
+
* Upgraded preferred Nginx version to 1.0.0.
|
7
|
+
* Phusion Passenger Standalone now pre-starts application processes
|
8
|
+
at startup instead of doing that at the first request.
|
9
|
+
* When sending data to Union Station, the HTTP status code is now also
|
10
|
+
logged.
|
11
|
+
* Various Union Station-related stability improvements.
|
12
|
+
* The Linux OOM killer was previously erroneously disabled for all
|
13
|
+
Phusion Passenger processes, including application processes. The
|
14
|
+
intention was to only disable it for the Watchdog. This has been
|
15
|
+
fixed, and the Watchdog is now the only process for which the OOM
|
16
|
+
killer is disabled.
|
17
|
+
* Fixed some compilation problems on OpenBSD.
|
18
|
+
* Due to a typo, the dependency on file-tail was not entirely removed
|
19
|
+
in 3.0.6. This has now been fixed.
|
20
|
+
|
21
|
+
|
1
22
|
Release 3.0.6
|
2
23
|
-------------
|
3
24
|
|
data/build/agents.rb
CHANGED
@@ -45,7 +45,6 @@ dependencies = [
|
|
45
45
|
'ext/common/LoggingAgent/Main.cpp',
|
46
46
|
'ext/common/LoggingAgent/LoggingServer.h',
|
47
47
|
'ext/common/LoggingAgent/RemoteSender.h',
|
48
|
-
'ext/common/LoggingAgent/ChangeNotifier.h',
|
49
48
|
'ext/common/LoggingAgent/DataStoreId.h',
|
50
49
|
'ext/common/LoggingAgent/FilterSupport.h',
|
51
50
|
'ext/common/ServerInstanceDir.h',
|
data/build/cxx_tests.rb
CHANGED
@@ -132,7 +132,6 @@ TEST_CXX_OBJECTS = {
|
|
132
132
|
test/cxx/LoggingTest.cpp
|
133
133
|
ext/common/LoggingAgent/LoggingServer.h
|
134
134
|
ext/common/LoggingAgent/RemoteSender.h
|
135
|
-
ext/common/LoggingAgent/ChangeNotifier.h
|
136
135
|
ext/common/LoggingAgent/DataStoreId.h
|
137
136
|
ext/common/LoggingAgent/FilterSupport.h
|
138
137
|
ext/common/Logging.h
|
data/doc/Users guide Apache.html
CHANGED
@@ -51,7 +51,7 @@
|
|
51
51
|
<a name="l00026"></a>00026 <span class="preprocessor"></span><span class="preprocessor">#define _PASSENGER_CONSTANTS_H_</span>
|
52
52
|
<a name="l00027"></a>00027 <span class="preprocessor"></span>
|
53
53
|
<a name="l00028"></a>00028 <span class="comment">/* Don't forget to update lib/phusion_passenger.rb too. */</span>
|
54
|
-
<a name="l00029"></a>00029 <span class="preprocessor">#define PASSENGER_VERSION "3.0.
|
54
|
+
<a name="l00029"></a>00029 <span class="preprocessor">#define PASSENGER_VERSION "3.0.7"</span>
|
55
55
|
<a name="l00030"></a>00030 <span class="preprocessor"></span>
|
56
56
|
<a name="l00031"></a>00031 <span class="preprocessor">#define FEEDBACK_FD 3</span>
|
57
57
|
<a name="l00032"></a>00032 <span class="preprocessor"></span>
|
@@ -53,13 +53,14 @@
|
|
53
53
|
<a name="l00028"></a>00028 <span class="preprocessor">#ifndef _PASSENGER_NGINX_STATIC_CONTENT_HANDLER_H_</span>
|
54
54
|
<a name="l00029"></a>00029 <span class="preprocessor"></span><span class="preprocessor">#define _PASSENGER_NGINX_STATIC_CONTENT_HANDLER_H_</span>
|
55
55
|
<a name="l00030"></a>00030 <span class="preprocessor"></span>
|
56
|
-
<a name="l00031"></a>00031 <span class="preprocessor">#include <
|
57
|
-
<a name="l00032"></a>00032 <span class="preprocessor">#include <
|
58
|
-
<a name="l00033"></a>00033
|
59
|
-
<a name="l00034"></a>00034
|
60
|
-
<a name="l00035"></a>00035
|
61
|
-
<a name="l00036"></a>00036
|
62
|
-
<a name="l00037"></a>00037
|
56
|
+
<a name="l00031"></a>00031 <span class="preprocessor">#include <ngx_config.h></span>
|
57
|
+
<a name="l00032"></a>00032 <span class="preprocessor">#include <ngx_core.h></span>
|
58
|
+
<a name="l00033"></a>00033 <span class="preprocessor">#include <ngx_http.h></span>
|
59
|
+
<a name="l00034"></a>00034
|
60
|
+
<a name="l00035"></a>00035 ngx_int_t passenger_static_content_handler(ngx_http_request_t *r,
|
61
|
+
<a name="l00036"></a>00036 ngx_str_t *filename);
|
62
|
+
<a name="l00037"></a>00037
|
63
|
+
<a name="l00038"></a>00038 <span class="preprocessor">#endif </span><span class="comment">/* _PASSENGER_NGINX_STATIC_CONTENT_HANDLER_H_ */</span>
|
63
64
|
</pre></div></div>
|
64
65
|
<hr size="1"/><address style="text-align: right;"><small>Generated by
|
65
66
|
<a href="http://www.doxygen.org/index.html">
|
data/doc/cxxapi/graph_legend.png
CHANGED
Binary file
|
data/doc/cxxapi/group__Core.html
CHANGED
@@ -26,7 +26,7 @@ Collaboration diagram for Core Apache-related classes and functions:</div>
|
|
26
26
|
<div class="dynsection">
|
27
27
|
<center><table><tr><td><img src="group__Core.png" border="0" alt="" usemap="#group____Core_map"/>
|
28
28
|
<map name="group____Core_map" id="group____Core">
|
29
|
-
<area shape="rect" id="node2" href="group__Hooks.html" title="Apache hooks" alt="" coords="
|
29
|
+
<area shape="rect" id="node2" href="group__Hooks.html" title="Apache hooks" alt="" coords="303,5,399,33"/></map></td></tr></table></center>
|
30
30
|
</div>
|
31
31
|
</p>
|
32
32
|
<table border="0" cellpadding="0" cellspacing="0">
|
data/doc/cxxapi/group__Core.map
CHANGED
data/doc/cxxapi/group__Core.png
CHANGED
Binary file
|
@@ -29,7 +29,7 @@ Collaboration diagram for Apache hooks:</div>
|
|
29
29
|
<div class="dynsection">
|
30
30
|
<center><table><tr><td><img src="group__Hooks.png" border="0" alt="" usemap="#group____Hooks_map"/>
|
31
31
|
<map name="group____Hooks_map" id="group____Hooks">
|
32
|
-
<area shape="rect" id="node1" href="group__Core.html" title="Core Apache-related classes and functions" alt="" coords="
|
32
|
+
<area shape="rect" id="node1" href="group__Core.html" title="Core Apache-related classes and functions" alt="" coords="5,5,253,33"/></map></td></tr></table></center>
|
33
33
|
</div>
|
34
34
|
</p>
|
35
35
|
<table border="0" cellpadding="0" cellspacing="0">
|
data/doc/cxxapi/group__Hooks.map
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
<map id="structs" name="structs">
|
2
|
-
<area shape="rect" id="node1" href="$group__Core.html" title="Core Apache-related classes and functions" alt="" coords="
|
2
|
+
<area shape="rect" id="node1" href="$group__Core.html" title="Core Apache-related classes and functions" alt="" coords="5,5,253,33"/>
|
3
3
|
</map>
|
data/doc/cxxapi/group__Hooks.png
CHANGED
Binary file
|
@@ -53,39 +53,40 @@
|
|
53
53
|
<a name="l00028"></a>00028 <span class="preprocessor">#ifndef _PASSENGER_NGINX_MODULE_H_</span>
|
54
54
|
<a name="l00029"></a>00029 <span class="preprocessor"></span><span class="preprocessor">#define _PASSENGER_NGINX_MODULE_H_</span>
|
55
55
|
<a name="l00030"></a>00030 <span class="preprocessor"></span>
|
56
|
-
<a name="l00031"></a>00031 <span class="preprocessor">#include <
|
57
|
-
<a name="l00032"></a>00032 <span class="preprocessor">#include &
|
58
|
-
<a name="l00033"></a>00033 <span class="preprocessor">#include "../common/
|
59
|
-
<a name="l00034"></a>00034 <span class="
|
60
|
-
<a name="l00035"></a>00035 <span class="comment"
|
61
|
-
<a name="l00036"></a>00036 <span class="comment"
|
62
|
-
<a name="l00037"></a>00037 <span class="comment"> *
|
63
|
-
<a name="l00038"></a>00038 <span class="comment">
|
64
|
-
<a name="l00039"></a>00039 <span class="
|
65
|
-
<a name="l00040"></a>00040 <span class="preprocessor"
|
66
|
-
<a name="l00041"></a>00041 <span class="preprocessor">
|
67
|
-
<a name="l00042"></a>00042 <span class="preprocessor">
|
68
|
-
<a name="l00043"></a>00043 <span class="preprocessor"
|
69
|
-
<a name="l00044"></a>00044 <span class="
|
70
|
-
<a name="l00045"></a>00045 <span class="
|
71
|
-
<a name="l00046"></a>00046 <span class="comment"
|
72
|
-
<a name="l00047"></a>00047 <span class="comment"
|
73
|
-
<a name="l00048"></a>00048 <span class="comment">
|
74
|
-
<a name="l00049"></a>00049 <span class="
|
75
|
-
<a name="l00050"></a>00050
|
76
|
-
<a name="l00051"></a>00051
|
77
|
-
<a name="l00052"></a>00052 <span class="
|
78
|
-
<a name="l00053"></a>00053 <span class="comment"
|
79
|
-
<a name="l00054"></a>00054 <span class="comment"
|
80
|
-
<a name="l00055"></a>00055 <span class="comment">
|
81
|
-
<a name="l00056"></a>00056 <span class="
|
82
|
-
<a name="l00057"></a>00057
|
83
|
-
<a name="l00058"></a>00058
|
84
|
-
<a name="l00059"></a>00059
|
85
|
-
<a name="l00060"></a>00060
|
86
|
-
<a name="l00061"></a>00061
|
87
|
-
<a name="l00062"></a>00062
|
88
|
-
<a name="l00063"></a>00063
|
56
|
+
<a name="l00031"></a>00031 <span class="preprocessor">#include <ngx_config.h></span>
|
57
|
+
<a name="l00032"></a>00032 <span class="preprocessor">#include <ngx_core.h></span>
|
58
|
+
<a name="l00033"></a>00033 <span class="preprocessor">#include "../common/AgentsStarter.h"</span>
|
59
|
+
<a name="l00034"></a>00034 <span class="preprocessor">#include "../common/Utils/CachedFileStat.h"</span>
|
60
|
+
<a name="l00035"></a>00035 <span class="comment"></span>
|
61
|
+
<a name="l00036"></a>00036 <span class="comment">/**</span>
|
62
|
+
<a name="l00037"></a>00037 <span class="comment"> * The Nginx version number as an integer.</span>
|
63
|
+
<a name="l00038"></a>00038 <span class="comment"> * For example, on nginx 1.7.30 this value is 1007030.</span>
|
64
|
+
<a name="l00039"></a>00039 <span class="comment"> */</span>
|
65
|
+
<a name="l00040"></a>00040 <span class="preprocessor">#define NGINX_VERSION_NUM \</span>
|
66
|
+
<a name="l00041"></a>00041 <span class="preprocessor"> (1000000 * PASSENGER_NGINX_MAJOR_VERSION + \</span>
|
67
|
+
<a name="l00042"></a>00042 <span class="preprocessor"> 1000 * PASSENGER_NGINX_MINOR_VERSION + \</span>
|
68
|
+
<a name="l00043"></a>00043 <span class="preprocessor"> PASSENGER_NGINX_MICRO_VERSION)</span>
|
69
|
+
<a name="l00044"></a>00044 <span class="preprocessor"></span>
|
70
|
+
<a name="l00045"></a>00045 <span class="keyword">extern</span> ngx_module_t ngx_http_passenger_module;
|
71
|
+
<a name="l00046"></a>00046 <span class="comment"></span>
|
72
|
+
<a name="l00047"></a>00047 <span class="comment">/**</span>
|
73
|
+
<a name="l00048"></a>00048 <span class="comment"> * A static schema string to be assigned to Nginx 'upstream' strctures.</span>
|
74
|
+
<a name="l00049"></a>00049 <span class="comment"> */</span>
|
75
|
+
<a name="l00050"></a>00050 <span class="keyword">extern</span> ngx_str_t passenger_schema_string;
|
76
|
+
<a name="l00051"></a>00051
|
77
|
+
<a name="l00052"></a>00052 <span class="keyword">extern</span> ngx_str_t passenger_placeholder_upstream_address;
|
78
|
+
<a name="l00053"></a>00053 <span class="comment"></span>
|
79
|
+
<a name="l00054"></a>00054 <span class="comment">/**</span>
|
80
|
+
<a name="l00055"></a>00055 <span class="comment"> * A CachedFileStat object used for caching stat() calls.</span>
|
81
|
+
<a name="l00056"></a>00056 <span class="comment"> */</span>
|
82
|
+
<a name="l00057"></a>00057 <span class="keyword">extern</span> PassengerCachedFileStat *passenger_stat_cache;
|
83
|
+
<a name="l00058"></a>00058
|
84
|
+
<a name="l00059"></a>00059 <span class="keyword">extern</span> AgentsStarter *passenger_agents_starter;
|
85
|
+
<a name="l00060"></a>00060
|
86
|
+
<a name="l00061"></a>00061 <span class="keyword">extern</span> ngx_cycle_t *passenger_current_cycle;
|
87
|
+
<a name="l00062"></a>00062
|
88
|
+
<a name="l00063"></a>00063 <span class="preprocessor">#endif </span><span class="comment">/* _PASSENGER_NGINX_MODULE_H_ */</span>
|
89
|
+
<a name="l00064"></a>00064
|
89
90
|
</pre></div></div>
|
90
91
|
<hr size="1"/><address style="text-align: right;"><small>Generated by
|
91
92
|
<a href="http://www.doxygen.org/index.html">
|
data/ext/apache2/Hooks.cpp
CHANGED
data/ext/common/AgentBase.cpp
CHANGED
@@ -154,8 +154,12 @@ appendSignalReason(char *buf, siginfo_t *info) {
|
|
154
154
|
#endif
|
155
155
|
SI_CODE_HANDLER(SI_QUEUE);
|
156
156
|
SI_CODE_HANDLER(SI_TIMER);
|
157
|
-
|
158
|
-
|
157
|
+
#ifdef SI_ASYNCIO
|
158
|
+
SI_CODE_HANDLER(SI_ASYNCIO);
|
159
|
+
#endif
|
160
|
+
#ifdef SI_MESGQ
|
161
|
+
SI_CODE_HANDLER(SI_MESGQ);
|
162
|
+
#endif
|
159
163
|
#ifdef SI_SIGIO
|
160
164
|
SI_CODE_HANDLER(SI_SIGIO);
|
161
165
|
#endif
|
data/ext/common/Constants.h
CHANGED
@@ -44,7 +44,6 @@
|
|
44
44
|
|
45
45
|
#include "DataStoreId.h"
|
46
46
|
#include "RemoteSender.h"
|
47
|
-
#include "ChangeNotifier.h"
|
48
47
|
#include "FilterSupport.h"
|
49
48
|
#include "../EventedMessageServer.h"
|
50
49
|
#include "../MessageReadersWriters.h"
|
@@ -121,7 +120,7 @@ private:
|
|
121
120
|
|
122
121
|
virtual void append(const DataStoreId &dataStoreId,
|
123
122
|
const StaticString &data) = 0;
|
124
|
-
virtual
|
123
|
+
virtual bool flush() { return true; }
|
125
124
|
virtual void dump(ostream &stream) const { }
|
126
125
|
};
|
127
126
|
|
@@ -133,12 +132,6 @@ private:
|
|
133
132
|
char buffer[BUFFER_CAPACITY];
|
134
133
|
unsigned int bufferSize;
|
135
134
|
|
136
|
-
/**
|
137
|
-
* Contains every (groupName, nodeName, category) tuple for
|
138
|
-
* which their data is currently buffered in this sink.
|
139
|
-
*/
|
140
|
-
set<DataStoreId> dataStoreIds;
|
141
|
-
|
142
135
|
LogFile(LoggingServer *server, const string &filename, mode_t filePermissions)
|
143
136
|
: LogSink(server)
|
144
137
|
{
|
@@ -163,22 +156,7 @@ private:
|
|
163
156
|
flush();
|
164
157
|
}
|
165
158
|
|
166
|
-
void notifyChanges() {
|
167
|
-
if (server->changeNotifier != NULL) {
|
168
|
-
set<DataStoreId>::const_iterator it;
|
169
|
-
set<DataStoreId>::const_iterator end = dataStoreIds.end();
|
170
|
-
|
171
|
-
for (it = dataStoreIds.begin(); it != dataStoreIds.end(); it++) {
|
172
|
-
server->changeNotifier->changed(*it);
|
173
|
-
}
|
174
|
-
}
|
175
|
-
dataStoreIds.clear();
|
176
|
-
}
|
177
|
-
|
178
159
|
virtual void append(const DataStoreId &dataStoreId, const StaticString &data) {
|
179
|
-
if (server->changeNotifier != NULL) {
|
180
|
-
dataStoreIds.insert(dataStoreId);
|
181
|
-
}
|
182
160
|
if (bufferSize + data.size() > BUFFER_CAPACITY) {
|
183
161
|
StaticString data2[2];
|
184
162
|
data2[0] = StaticString(buffer, bufferSize);
|
@@ -187,19 +165,20 @@ private:
|
|
187
165
|
gatheredWrite(fd, data2, 2);
|
188
166
|
lastFlushed = ev_now(server->getLoop());
|
189
167
|
bufferSize = 0;
|
190
|
-
notifyChanges();
|
191
168
|
} else {
|
192
169
|
memcpy(buffer + bufferSize, data.data(), data.size());
|
193
170
|
bufferSize += data.size();
|
194
171
|
}
|
195
172
|
}
|
196
173
|
|
197
|
-
virtual
|
174
|
+
virtual bool flush() {
|
198
175
|
if (bufferSize > 0) {
|
199
176
|
lastFlushed = ev_now(server->getLoop());
|
200
177
|
writeExact(fd, buffer, bufferSize);
|
201
178
|
bufferSize = 0;
|
202
|
-
|
179
|
+
return true;
|
180
|
+
} else {
|
181
|
+
return false;
|
203
182
|
}
|
204
183
|
}
|
205
184
|
|
@@ -270,13 +249,16 @@ private:
|
|
270
249
|
}
|
271
250
|
}
|
272
251
|
|
273
|
-
virtual
|
252
|
+
virtual bool flush() {
|
274
253
|
if (bufferSize > 0) {
|
275
254
|
lastFlushed = ev_now(server->getLoop());
|
276
255
|
StaticString data(buffer, bufferSize);
|
277
256
|
server->remoteSender.schedule(unionStationKey, nodeName,
|
278
257
|
category, &data, 1);
|
279
258
|
bufferSize = 0;
|
259
|
+
return true;
|
260
|
+
} else {
|
261
|
+
return false;
|
280
262
|
}
|
281
263
|
}
|
282
264
|
|
@@ -376,8 +358,7 @@ private:
|
|
376
358
|
|
377
359
|
enum ClientType {
|
378
360
|
UNINITIALIZED,
|
379
|
-
LOGGER
|
380
|
-
WATCHER
|
361
|
+
LOGGER
|
381
362
|
};
|
382
363
|
|
383
364
|
struct Client: public EventedMessageClient {
|
@@ -411,7 +392,6 @@ private:
|
|
411
392
|
string dirPermissions;
|
412
393
|
mode_t filePermissions;
|
413
394
|
RemoteSender remoteSender;
|
414
|
-
ChangeNotifierPtr changeNotifier;
|
415
395
|
ev::timer garbageCollectionTimer;
|
416
396
|
ev::timer sinkFlushingTimer;
|
417
397
|
ev::timer exitTimer;
|
@@ -820,58 +800,6 @@ private:
|
|
820
800
|
return true;
|
821
801
|
}
|
822
802
|
|
823
|
-
bool getLastEntryInDirectory(const string &path, string &result) const {
|
824
|
-
DIR *dir = opendir(path.c_str());
|
825
|
-
struct dirent *entry;
|
826
|
-
vector<string> subdirs;
|
827
|
-
|
828
|
-
if (dir == NULL) {
|
829
|
-
int e = errno;
|
830
|
-
throw FileSystemException("Cannot open directory " + path,
|
831
|
-
e, path);
|
832
|
-
}
|
833
|
-
while ((entry = readdir(dir)) != NULL) {
|
834
|
-
if (isDirectory(path, entry) && looksLikeNumber(entry->d_name)) {
|
835
|
-
subdirs.push_back(entry->d_name);
|
836
|
-
}
|
837
|
-
}
|
838
|
-
closedir(dir);
|
839
|
-
|
840
|
-
if (subdirs.empty()) {
|
841
|
-
return false;
|
842
|
-
}
|
843
|
-
|
844
|
-
vector<string>::const_iterator it = subdirs.begin();
|
845
|
-
vector<string>::const_iterator end = subdirs.end();
|
846
|
-
vector<string>::const_iterator largest_it = subdirs.begin();
|
847
|
-
int largest = atoi(subdirs[0]);
|
848
|
-
for (it++; it != end; it++) {
|
849
|
-
const string &subdir = *it;
|
850
|
-
int number = atoi(subdir.c_str());
|
851
|
-
if (number > largest) {
|
852
|
-
largest_it = it;
|
853
|
-
largest = number;
|
854
|
-
}
|
855
|
-
}
|
856
|
-
result = *largest_it;
|
857
|
-
return true;
|
858
|
-
}
|
859
|
-
|
860
|
-
static void pendingDataFlushed(EventedClient *_client) {
|
861
|
-
Client *client = (Client *) _client;
|
862
|
-
LoggingServer *self = (LoggingServer *) client->userData;
|
863
|
-
|
864
|
-
client->onPendingDataFlushed = NULL;
|
865
|
-
if (OXT_UNLIKELY( client->type != WATCHER )) {
|
866
|
-
P_WARN("BUG: pendingDataFlushed() called even though client type is not WATCHER.");
|
867
|
-
client->disconnect();
|
868
|
-
} else if (self->changeNotifier != NULL) {
|
869
|
-
self->changeNotifier->addClient(client->detach());
|
870
|
-
} else {
|
871
|
-
client->disconnect();
|
872
|
-
}
|
873
|
-
}
|
874
|
-
|
875
803
|
/* Release all inactive log sinks that have been inactive for more than
|
876
804
|
* GARBAGE_COLLECTION_TIMEOUT seconds.
|
877
805
|
*/
|
@@ -1160,26 +1088,6 @@ protected:
|
|
1160
1088
|
client->type = LOGGER;
|
1161
1089
|
client->writeArrayMessage("ok", NULL);
|
1162
1090
|
|
1163
|
-
} else if (args[0] == "watchChanges") {
|
1164
|
-
if (OXT_UNLIKELY( !checkWhetherConnectionAreAcceptable(client) )) {
|
1165
|
-
return true;
|
1166
|
-
}
|
1167
|
-
if (OXT_UNLIKELY( client->type != UNINITIALIZED )) {
|
1168
|
-
sendErrorToClient(client, "This command cannot be invoked "
|
1169
|
-
"if the 'init' command is already invoked.");
|
1170
|
-
client->disconnect();
|
1171
|
-
return true;
|
1172
|
-
}
|
1173
|
-
|
1174
|
-
client->type = WATCHER;
|
1175
|
-
client->notifyReads(false);
|
1176
|
-
discardReadData();
|
1177
|
-
|
1178
|
-
// Add to the change notifier after all pending data
|
1179
|
-
// has been written out.
|
1180
|
-
client->onPendingDataFlushed = pendingDataFlushed;
|
1181
|
-
client->writeArrayMessage("ok", NULL);
|
1182
|
-
|
1183
1091
|
} else if (args[0] == "flush") {
|
1184
1092
|
flushAllSinks();
|
1185
1093
|
client->writeArrayMessage("ok", NULL);
|
@@ -1334,79 +1242,18 @@ public:
|
|
1334
1242
|
}
|
1335
1243
|
|
1336
1244
|
// Invoke destructors, causing all transactions and log sinks to
|
1337
|
-
// be flushed before RemoteSender
|
1338
|
-
// destroyed.
|
1245
|
+
// be flushed before RemoteSender is being destroyed.
|
1339
1246
|
transactions.clear();
|
1340
1247
|
logSinkCache.clear();
|
1341
1248
|
inactiveLogSinks.clear();
|
1342
1249
|
}
|
1343
1250
|
|
1344
|
-
void setChangeNotifier(const ChangeNotifierPtr &_changeNotifier) {
|
1345
|
-
changeNotifier = _changeNotifier;
|
1346
|
-
changeNotifier->getLastPos = boost::bind(&LoggingServer::getLastPos,
|
1347
|
-
this, _1, _2, _3);
|
1348
|
-
}
|
1349
|
-
|
1350
|
-
string getLastPos(const StaticString &groupName, const StaticString &nodeName,
|
1351
|
-
const StaticString &category) const
|
1352
|
-
{
|
1353
|
-
md5_state_t state;
|
1354
|
-
md5_byte_t digest[MD5_SIZE];
|
1355
|
-
char nodeId[MD5_HEX_SIZE];
|
1356
|
-
md5_init(&state);
|
1357
|
-
md5_append(&state, (const md5_byte_t *) nodeName.data(), nodeName.size());
|
1358
|
-
md5_finish(&state, digest);
|
1359
|
-
toHex(StaticString((const char *) digest, MD5_SIZE), nodeId);
|
1360
|
-
|
1361
|
-
string dir = determineFilename(groupName, nodeId, category);
|
1362
|
-
string subdir, component;
|
1363
|
-
subdir.reserve(13); // It's a string that looks like: "2010/06/24/12"
|
1364
|
-
|
1365
|
-
try {
|
1366
|
-
// Loop 4 times to process year, month, day, hour.
|
1367
|
-
for (int i = 0; i < 4; i++) {
|
1368
|
-
bool found = getLastEntryInDirectory(dir, component);
|
1369
|
-
if (!found) {
|
1370
|
-
return string();
|
1371
|
-
}
|
1372
|
-
dir.append("/");
|
1373
|
-
dir.append(component);
|
1374
|
-
if (i != 0) {
|
1375
|
-
subdir.append("/");
|
1376
|
-
}
|
1377
|
-
subdir.append(component);
|
1378
|
-
}
|
1379
|
-
// After the loop, new dir == old dir + "/" + subdir
|
1380
|
-
} catch (const SystemException &e) {
|
1381
|
-
if (e.code() == ENOENT) {
|
1382
|
-
return string();
|
1383
|
-
} else {
|
1384
|
-
throw;
|
1385
|
-
}
|
1386
|
-
}
|
1387
|
-
|
1388
|
-
string &filename = dir;
|
1389
|
-
filename.append("/log.txt");
|
1390
|
-
|
1391
|
-
struct stat buf;
|
1392
|
-
if (stat(filename.c_str(), &buf) == -1) {
|
1393
|
-
if (errno == ENOENT) {
|
1394
|
-
return string();
|
1395
|
-
} else {
|
1396
|
-
int e = errno;
|
1397
|
-
throw FileSystemException("Cannot stat() " + filename, e,
|
1398
|
-
filename);
|
1399
|
-
}
|
1400
|
-
} else {
|
1401
|
-
return subdir + "/" + toString(buf.st_size);
|
1402
|
-
}
|
1403
|
-
}
|
1404
|
-
|
1405
1251
|
void dump(ostream &stream) const {
|
1406
1252
|
TransactionMap::const_iterator it;
|
1407
1253
|
TransactionMap::const_iterator end = transactions.end();
|
1408
1254
|
|
1409
|
-
stream << "Number of clients: " << getClients().size() << "\n";
|
1255
|
+
stream << "Number of clients : " << getClients().size() << "\n";
|
1256
|
+
stream << "RemoteSender queue: " << remoteSender.queued() << " items\n";
|
1410
1257
|
stream << "Open transactions: " << transactions.size() << "\n";
|
1411
1258
|
for (it = transactions.begin(); it != end; it++) {
|
1412
1259
|
const TransactionPtr &transaction = it->second;
|
@@ -97,6 +97,8 @@ private:
|
|
97
97
|
throw IOException("Unable to create a CURL handle");
|
98
98
|
}
|
99
99
|
}
|
100
|
+
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
|
101
|
+
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 180);
|
100
102
|
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, lastErrorMessage);
|
101
103
|
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
|
102
104
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curlDataReceived);
|
@@ -467,7 +469,13 @@ public:
|
|
467
469
|
}
|
468
470
|
}
|
469
471
|
|
470
|
-
queue.
|
472
|
+
if (!queue.tryAdd(item)) {
|
473
|
+
P_WARN("The Union Station gateway isn't responding quickly enough; dropping packet.");
|
474
|
+
}
|
475
|
+
}
|
476
|
+
|
477
|
+
unsigned int queued() const {
|
478
|
+
return queue.size();
|
471
479
|
}
|
472
480
|
};
|
473
481
|
|
@@ -37,7 +37,7 @@ using namespace boost;
|
|
37
37
|
template<typename T>
|
38
38
|
class BlockingQueue {
|
39
39
|
private:
|
40
|
-
timed_mutex lock;
|
40
|
+
mutable timed_mutex lock;
|
41
41
|
condition_variable_any added;
|
42
42
|
condition_variable_any removed;
|
43
43
|
unsigned int max;
|
@@ -52,6 +52,11 @@ public:
|
|
52
52
|
this->max = max;
|
53
53
|
}
|
54
54
|
|
55
|
+
unsigned int size() const {
|
56
|
+
lock_guard<timed_mutex> l(lock);
|
57
|
+
return queue.size();
|
58
|
+
}
|
59
|
+
|
55
60
|
void add(const T &item) {
|
56
61
|
unique_lock<timed_mutex> l(lock);
|
57
62
|
while (atMaxCapacity()) {
|
@@ -64,6 +69,20 @@ public:
|
|
64
69
|
}
|
65
70
|
}
|
66
71
|
|
72
|
+
bool tryAdd(const T &item) {
|
73
|
+
lock_guard<timed_mutex> l(lock);
|
74
|
+
if (!atMaxCapacity()) {
|
75
|
+
queue.push(item);
|
76
|
+
added.notify_one();
|
77
|
+
if (!atMaxCapacity()) {
|
78
|
+
removed.notify_one();
|
79
|
+
}
|
80
|
+
return true;
|
81
|
+
} else {
|
82
|
+
return false;
|
83
|
+
}
|
84
|
+
}
|
85
|
+
|
67
86
|
T get() {
|
68
87
|
unique_lock<timed_mutex> l(lock);
|
69
88
|
while (queue.empty()) {
|
data/ext/common/Watchdog.cpp
CHANGED
@@ -47,6 +47,7 @@
|
|
47
47
|
#include "RandomGenerator.h"
|
48
48
|
#include "Logging.h"
|
49
49
|
#include "Exceptions.h"
|
50
|
+
#include "StaticString.h"
|
50
51
|
#include "ResourceLocator.h"
|
51
52
|
#include "Utils.h"
|
52
53
|
#include "Utils/Base64.h"
|
@@ -79,6 +80,7 @@ static unsigned int maxInstancesPerApp;
|
|
79
80
|
static unsigned int poolIdleTime;
|
80
81
|
static string serializedPrestartURLs;
|
81
82
|
|
83
|
+
static string oldOomScore;
|
82
84
|
static ServerInstanceDirPtr serverInstanceDir;
|
83
85
|
static ServerInstanceDir::GenerationPtr generation;
|
84
86
|
static string loggingAgentAddress;
|
@@ -88,6 +90,8 @@ static EventFd *errorEvent;
|
|
88
90
|
|
89
91
|
#define REQUEST_SOCKET_PASSWORD_SIZE 64
|
90
92
|
|
93
|
+
static string setOomScore(const StaticString &score);
|
94
|
+
|
91
95
|
|
92
96
|
/**
|
93
97
|
* Abstract base class for watching agent processes.
|
@@ -100,7 +104,7 @@ private:
|
|
100
104
|
void threadMain() {
|
101
105
|
try {
|
102
106
|
pid_t pid, ret;
|
103
|
-
int status;
|
107
|
+
int status, e;
|
104
108
|
|
105
109
|
while (!this_thread::interruption_requested()) {
|
106
110
|
lock.lock();
|
@@ -123,6 +127,9 @@ private:
|
|
123
127
|
P_WARN("waitpid() on " << name() << " return -1 with " <<
|
124
128
|
"errno = ECHILD, falling back to kill polling");
|
125
129
|
waitpidUsingKillPolling(pid);
|
130
|
+
e = 0;
|
131
|
+
} else {
|
132
|
+
e = errno;
|
126
133
|
}
|
127
134
|
|
128
135
|
lock.lock();
|
@@ -132,7 +139,6 @@ private:
|
|
132
139
|
this_thread::disable_interruption di;
|
133
140
|
this_thread::disable_syscall_interruption dsi;
|
134
141
|
if (ret == -1) {
|
135
|
-
int e = errno;
|
136
142
|
P_WARN(name() << " crashed or killed for "
|
137
143
|
"an unknown reason (errno = " <<
|
138
144
|
strerror(e) << "), restarting it...");
|
@@ -345,6 +351,8 @@ public:
|
|
345
351
|
* agent as well as all its descendant processes. */
|
346
352
|
setpgid(getpid(), getpid());
|
347
353
|
|
354
|
+
setOomScore(oldOomScore);
|
355
|
+
|
348
356
|
try {
|
349
357
|
execProgram();
|
350
358
|
} catch (...) {
|
@@ -715,6 +723,8 @@ private:
|
|
715
723
|
_exit(1);
|
716
724
|
}
|
717
725
|
|
726
|
+
setOomScore(oldOomScore);
|
727
|
+
|
718
728
|
execlp("/bin/sh", "/bin/sh", "-c", "find . | xargs touch", (char *) 0);
|
719
729
|
e = errno;
|
720
730
|
fprintf(stderr, "Cannot execute 'find . | xargs touch': %s (%d)\n",
|
@@ -748,22 +758,44 @@ public:
|
|
748
758
|
|
749
759
|
|
750
760
|
/**
|
751
|
-
*
|
752
|
-
*
|
753
|
-
*
|
754
|
-
* the system administrator will have to restart the web server for Phusion
|
755
|
-
* Passenger to be usable again. So in this function we do whatever is necessary
|
756
|
-
* to prevent this watchdog process from becoming a candidate for the OS's
|
757
|
-
* Out-Of-Memory Killer.
|
761
|
+
* Linux-only way to change OOM killer configuration for
|
762
|
+
* current process. Requires root privileges, which we
|
763
|
+
* should have.
|
758
764
|
*/
|
759
|
-
static
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
|
765
|
+
static string
|
766
|
+
setOomScore(const StaticString &score) {
|
767
|
+
if (!score.empty()) {
|
768
|
+
string oldScore;
|
769
|
+
|
770
|
+
FILE *f = fopen("/proc/self/oom_adj", "r");
|
771
|
+
if (f == NULL) {
|
772
|
+
return "";
|
773
|
+
}
|
774
|
+
char buf[1024];
|
775
|
+
size_t bytesRead;
|
776
|
+
while (true) {
|
777
|
+
bytesRead = fread(buf, 1, sizeof(buf), f);
|
778
|
+
if (bytesRead == 0 && feof(f)) {
|
779
|
+
break;
|
780
|
+
} else if (bytesRead == 0 && ferror(f)) {
|
781
|
+
fclose(f);
|
782
|
+
return "";
|
783
|
+
} else {
|
784
|
+
oldScore.append(buf, bytesRead);
|
785
|
+
}
|
786
|
+
}
|
787
|
+
fclose(f);
|
788
|
+
|
789
|
+
f = fopen("/proc/self/oom_adj", "w");
|
790
|
+
if (f == NULL) {
|
791
|
+
return "";
|
792
|
+
}
|
793
|
+
fwrite(score.data(), 1, score.size(), f);
|
766
794
|
fclose(f);
|
795
|
+
|
796
|
+
return oldScore;
|
797
|
+
} else {
|
798
|
+
return "";
|
767
799
|
}
|
768
800
|
}
|
769
801
|
|
@@ -917,7 +949,16 @@ forceAllAgentsShutdown(vector<AgentWatcher *> &watchers) {
|
|
917
949
|
|
918
950
|
int
|
919
951
|
main(int argc, char *argv[]) {
|
920
|
-
|
952
|
+
/*
|
953
|
+
* Most operating systems overcommit memory. We *know* that this watchdog process
|
954
|
+
* doesn't use much memory; on OS X it uses about 200 KB of private RSS. If the
|
955
|
+
* watchdog is killed by the system Out-Of-Memory Killer or then it's all over:
|
956
|
+
* the system administrator will have to restart the web server for Phusion
|
957
|
+
* Passenger to be usable again. So here we disable Linux's OOM killer
|
958
|
+
* for this watchdog. Note that the OOM score is inherited by child processes
|
959
|
+
* so we need to restore it after each fork().
|
960
|
+
*/
|
961
|
+
oldOomScore = setOomScore("-17");
|
921
962
|
|
922
963
|
agentsOptions = initializeAgent(argc, argv, "PassengerWatchdog");
|
923
964
|
logLevel = agentsOptions.getInt("log_level");
|
data/ext/nginx/HelperAgent.cpp
CHANGED
@@ -313,7 +313,9 @@ private:
|
|
313
313
|
* before we were able to send back the
|
314
314
|
* full response.
|
315
315
|
*/
|
316
|
-
void forwardResponse(SessionPtr &session, FileDescriptor &clientFd
|
316
|
+
void forwardResponse(SessionPtr &session, FileDescriptor &clientFd,
|
317
|
+
const AnalyticsLogPtr &log)
|
318
|
+
{
|
317
319
|
TRACE_POINT();
|
318
320
|
HttpStatusExtractor ex;
|
319
321
|
int stream = session->getStream();
|
@@ -345,6 +347,11 @@ private:
|
|
345
347
|
writeExact(clientFd, statusLine);
|
346
348
|
UPDATE_TRACE_POINT();
|
347
349
|
writeExact(clientFd, ex.getBuffer());
|
350
|
+
if (!log->isNull()) {
|
351
|
+
string partialStatusLine = ex.getStatusLine();
|
352
|
+
partialStatusLine.erase(partialStatusLine.size() - 2, 2);
|
353
|
+
log->message("Status: " + partialStatusLine);
|
354
|
+
}
|
348
355
|
break;
|
349
356
|
} catch (const SystemException &e) {
|
350
357
|
if (e.code() == EPIPE) {
|
@@ -555,7 +562,7 @@ private:
|
|
555
562
|
scope.success();
|
556
563
|
}
|
557
564
|
|
558
|
-
forwardResponse(session, clientFd);
|
565
|
+
forwardResponse(session, clientFd, log);
|
559
566
|
|
560
567
|
requestProxyingScope.success();
|
561
568
|
} catch (const SpawnException &e) {
|
data/lib/phusion_passenger.rb
CHANGED
@@ -25,10 +25,10 @@ module PhusionPassenger
|
|
25
25
|
###### Version numbers ######
|
26
26
|
|
27
27
|
# Phusion Passenger version number. Don't forget to edit ext/common/Constants.h too.
|
28
|
-
VERSION_STRING = '3.0.
|
28
|
+
VERSION_STRING = '3.0.7'
|
29
29
|
|
30
|
-
PREFERRED_NGINX_VERSION = '0.
|
31
|
-
PREFERRED_PCRE_VERSION = '8.
|
30
|
+
PREFERRED_NGINX_VERSION = '1.0.0'
|
31
|
+
PREFERRED_PCRE_VERSION = '8.12'
|
32
32
|
STANDALONE_INTERFACE_VERSION = 1
|
33
33
|
|
34
34
|
|
@@ -274,7 +274,7 @@ module PlatformInfo
|
|
274
274
|
# headers are placed into the same directory as the Apache headers,
|
275
275
|
# and so 'apr-config' and 'apu-config' won't be necessary in that case.
|
276
276
|
def self.apr_config_needed_for_building_apache_modules?
|
277
|
-
filename = File.join("#{
|
277
|
+
filename = File.join("#{tmpexedir}/passenger-platform-check-#{Process.pid}.c")
|
278
278
|
File.open(filename, "w") do |f|
|
279
279
|
f.puts("#include <apr.h>")
|
280
280
|
end
|
@@ -57,7 +57,6 @@ class StartCommand < Command
|
|
57
57
|
sanity_check_options
|
58
58
|
|
59
59
|
ensure_nginx_installed
|
60
|
-
require_file_tail if should_watch_logs?
|
61
60
|
determine_various_resource_locations
|
62
61
|
require_app_finder
|
63
62
|
@app_finder = AppFinder.new(@args, @options)
|
@@ -105,15 +104,6 @@ class StartCommand < Command
|
|
105
104
|
end
|
106
105
|
|
107
106
|
private
|
108
|
-
def require_file_tail
|
109
|
-
begin
|
110
|
-
require 'file/tail'
|
111
|
-
rescue LoadError
|
112
|
-
error "Please install file-tail first: sudo gem install file-tail"
|
113
|
-
exit 1
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
107
|
def require_file_utils
|
118
108
|
require 'fileutils' unless defined?(FileUtils)
|
119
109
|
end
|
@@ -433,7 +423,6 @@ private
|
|
433
423
|
end
|
434
424
|
|
435
425
|
def watch_log_files_in_background
|
436
|
-
require_file_tail
|
437
426
|
@apps.each do |app|
|
438
427
|
thread = Thread.new do
|
439
428
|
watch_log_file("#{app[:root]}/log/#{@options[:env]}.log")
|
data/test/cxx/LoggingTest.cpp
CHANGED
@@ -114,33 +114,6 @@ namespace tut {
|
|
114
114
|
}
|
115
115
|
return client;
|
116
116
|
}
|
117
|
-
|
118
|
-
void setChangeNotifier(const ChangeNotifierPtr ¬ifier) {
|
119
|
-
server->setChangeNotifier(notifier);
|
120
|
-
}
|
121
|
-
|
122
|
-
|
123
|
-
class MyChangeNotifier: public ChangeNotifier {
|
124
|
-
public:
|
125
|
-
boost::mutex lock;
|
126
|
-
AtomicInt added;
|
127
|
-
set<DataStoreId> changes;
|
128
|
-
|
129
|
-
MyChangeNotifier(struct ev_loop *loop)
|
130
|
-
: ChangeNotifier(loop)
|
131
|
-
{ }
|
132
|
-
|
133
|
-
virtual void addClient(const FileDescriptor &fd) {
|
134
|
-
added = added + 1;
|
135
|
-
}
|
136
|
-
|
137
|
-
virtual void changed(const DataStoreId &dataStoreId) {
|
138
|
-
lock_guard<boost::mutex> l(lock);
|
139
|
-
changes.insert(dataStoreId);
|
140
|
-
}
|
141
|
-
};
|
142
|
-
|
143
|
-
typedef shared_ptr<MyChangeNotifier> MyChangeNotifierPtr;
|
144
117
|
};
|
145
118
|
|
146
119
|
DEFINE_TEST_GROUP(LoggingTest);
|
@@ -555,53 +528,6 @@ namespace tut {
|
|
555
528
|
}
|
556
529
|
}
|
557
530
|
|
558
|
-
TEST_METHOD(19) {
|
559
|
-
// getLastPos() works
|
560
|
-
SystemTime::forceAll(YESTERDAY);
|
561
|
-
|
562
|
-
AnalyticsLogPtr log = logger->newTransaction("foobar");
|
563
|
-
log->message("hello world");
|
564
|
-
log->flushToDiskAfterClose(true);
|
565
|
-
log.reset();
|
566
|
-
|
567
|
-
SystemTime::forceAll(TODAY);
|
568
|
-
|
569
|
-
log = logger->newTransaction("foobar");
|
570
|
-
log->message("hello world");
|
571
|
-
log->flushToDiskAfterClose(true);
|
572
|
-
log.reset();
|
573
|
-
|
574
|
-
stopLoggingServer(false);
|
575
|
-
|
576
|
-
string filename = loggingDir + "/1/" FOOBAR_LOCALHOST_PREFIX "/requests/2010/01/13/12/log.txt";
|
577
|
-
struct stat buf;
|
578
|
-
ensure_equals(stat(filename.c_str(), &buf), 0);
|
579
|
-
string lastPos = server->getLastPos("foobar", "localhost", "requests");
|
580
|
-
ensure_equals(lastPos, "2010/01/13/12/" + toString(buf.st_size));
|
581
|
-
}
|
582
|
-
|
583
|
-
TEST_METHOD(20) {
|
584
|
-
// getLastPos() returns the empty string if log.txt or if one of
|
585
|
-
// the subdirectories are missing.
|
586
|
-
SystemTime::forceAll(YESTERDAY);
|
587
|
-
|
588
|
-
AnalyticsLogPtr log = logger->newTransaction("foobar");
|
589
|
-
log->message("hello world");
|
590
|
-
log->flushToDiskAfterClose(true);
|
591
|
-
log.reset();
|
592
|
-
|
593
|
-
stopLoggingServer(false);
|
594
|
-
|
595
|
-
string filename = loggingDir + "/1/" FOOBAR_LOCALHOST_PREFIX "/requests/2010/01/12/12/log.txt";
|
596
|
-
unlink(filename.c_str());
|
597
|
-
|
598
|
-
string lastPos = server->getLastPos("foobar", "localhost", "requests");
|
599
|
-
ensure_equals(lastPos, "");
|
600
|
-
|
601
|
-
lastPos = server->getLastPos("baz", "localhost", "requests");
|
602
|
-
ensure_equals(lastPos, "");
|
603
|
-
}
|
604
|
-
|
605
531
|
TEST_METHOD(21) {
|
606
532
|
// The server temporarily buffers data in memory.
|
607
533
|
SystemTime::forceAll(YESTERDAY);
|
@@ -806,92 +732,7 @@ namespace tut {
|
|
806
732
|
ensure(log->isNull());
|
807
733
|
}
|
808
734
|
|
809
|
-
TEST_METHOD(
|
810
|
-
// The "watchChanges" command causes the server to detach the
|
811
|
-
// client and to pass it to the change notifier.
|
812
|
-
MyChangeNotifierPtr notifier(new MyChangeNotifier(eventLoop));
|
813
|
-
stopLoggingServer();
|
814
|
-
startLoggingServer(boost::bind(&LoggingTest::setChangeNotifier, this, notifier));
|
815
|
-
|
816
|
-
vector<string> args;
|
817
|
-
MessageClient client = createConnection(false);
|
818
|
-
client.write("watchChanges", NULL, NULL);
|
819
|
-
ensure(client.read(args));
|
820
|
-
EVENTUALLY(1,
|
821
|
-
result = notifier->added == 1;
|
822
|
-
);
|
823
|
-
// MyChangeNotifier doesn't store the client file descriptor
|
824
|
-
// so should be closed.
|
825
|
-
ensure(!client.read(args));
|
826
|
-
}
|
827
|
-
|
828
|
-
TEST_METHOD(31) {
|
829
|
-
// The server notifies the given ChangeNotifier with the
|
830
|
-
// appropriate changes whenever a log file sink is flushed.
|
831
|
-
MyChangeNotifierPtr notifier(new MyChangeNotifier(eventLoop));
|
832
|
-
stopLoggingServer();
|
833
|
-
startLoggingServer(boost::bind(&LoggingTest::setChangeNotifier, this, notifier));
|
834
|
-
|
835
|
-
AnalyticsLogPtr log = logger->newTransaction("foo", "requests");
|
836
|
-
log->message("hello world");
|
837
|
-
log.reset();
|
838
|
-
|
839
|
-
log = logger->newTransaction("bar", "requests");
|
840
|
-
log->message("hello world");
|
841
|
-
log.reset();
|
842
|
-
|
843
|
-
SHOULD_NEVER_HAPPEN(100,
|
844
|
-
lock_guard<boost::mutex> l(notifier->lock);
|
845
|
-
result = !notifier->changes.empty();
|
846
|
-
);
|
847
|
-
|
848
|
-
MessageChannel channel(logger->getConnection());
|
849
|
-
vector<string> args;
|
850
|
-
channel.write("flush", NULL);
|
851
|
-
ensure("(1)", channel.read(args));
|
852
|
-
|
853
|
-
EVENTUALLY(1,
|
854
|
-
lock_guard<boost::mutex> l(notifier->lock);
|
855
|
-
result = notifier->changes.size() == 2;
|
856
|
-
);
|
857
|
-
unique_lock<boost::mutex> l(notifier->lock);
|
858
|
-
ensure("(2)",
|
859
|
-
notifier->changes.find(DataStoreId("foo", "localhost", "requests")) !=
|
860
|
-
notifier->changes.end());
|
861
|
-
ensure("(3)",
|
862
|
-
notifier->changes.find(DataStoreId("bar", "localhost", "requests")) !=
|
863
|
-
notifier->changes.end());
|
864
|
-
notifier->changes.clear();
|
865
|
-
l.unlock();
|
866
|
-
|
867
|
-
|
868
|
-
log = logger->newTransaction("baz", "exceptions");
|
869
|
-
log->message("hello world");
|
870
|
-
log.reset();
|
871
|
-
|
872
|
-
channel.write("flush", NULL);
|
873
|
-
ensure("(4)", channel.read(args));
|
874
|
-
|
875
|
-
log = logger->newTransaction("bazz", "exceptions");
|
876
|
-
log->message("hello world");
|
877
|
-
log.reset();
|
878
|
-
|
879
|
-
EVENTUALLY(1,
|
880
|
-
lock_guard<boost::mutex> l(notifier->lock);
|
881
|
-
result = notifier->changes.size() == 1;
|
882
|
-
);
|
883
|
-
l.lock();
|
884
|
-
ensure("(5)",
|
885
|
-
notifier->changes.find(DataStoreId("baz", "localhost", "exceptions")) !=
|
886
|
-
notifier->changes.end());
|
887
|
-
l.unlock();
|
888
|
-
SHOULD_NEVER_HAPPEN(100,
|
889
|
-
lock_guard<boost::mutex> l(notifier->lock);
|
890
|
-
result = notifier->changes.size() != 1;
|
891
|
-
);
|
892
|
-
}
|
893
|
-
|
894
|
-
TEST_METHOD(32) {
|
735
|
+
TEST_METHOD(29) {
|
895
736
|
// One can supply a custom node name per openTransaction command.
|
896
737
|
MessageClient client1 = createConnection();
|
897
738
|
vector<string> args;
|
@@ -910,7 +751,7 @@ namespace tut {
|
|
910
751
|
ensure(fileExists(filename));
|
911
752
|
}
|
912
753
|
|
913
|
-
TEST_METHOD(
|
754
|
+
TEST_METHOD(30) {
|
914
755
|
// A transaction is only written to the sink if it passes all given filters.
|
915
756
|
// Test logging of new transaction.
|
916
757
|
SystemTime::forceAll(YESTERDAY);
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: passenger
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 9
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 3
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 3.0.
|
9
|
+
- 7
|
10
|
+
version: 3.0.7
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Phusion - http://www.phusion.nl/
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-04-
|
18
|
+
date: 2011-04-14 00:00:00 +02:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -730,7 +730,6 @@ files:
|
|
730
730
|
- ext/common/HelperAgent/BacktracesServer.h
|
731
731
|
- ext/common/IniFile.h
|
732
732
|
- ext/common/Logging.h
|
733
|
-
- ext/common/LoggingAgent/ChangeNotifier.h
|
734
733
|
- ext/common/LoggingAgent/DataStoreId.h
|
735
734
|
- ext/common/LoggingAgent/FilterSupport.h
|
736
735
|
- ext/common/LoggingAgent/LoggingServer.h
|
@@ -1,63 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
* Phusion Passenger - http://www.modrails.com/
|
3
|
-
* Copyright (c) 2010 Phusion
|
4
|
-
*
|
5
|
-
* "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
|
6
|
-
*
|
7
|
-
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
-
* of this software and associated documentation files (the "Software"), to deal
|
9
|
-
* in the Software without restriction, including without limitation the rights
|
10
|
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11
|
-
* copies of the Software, and to permit persons to whom the Software is
|
12
|
-
* furnished to do so, subject to the following conditions:
|
13
|
-
*
|
14
|
-
* The above copyright notice and this permission notice shall be included in
|
15
|
-
* all copies or substantial portions of the Software.
|
16
|
-
*
|
17
|
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22
|
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23
|
-
* THE SOFTWARE.
|
24
|
-
*/
|
25
|
-
#ifndef _PASSENGER_CHANGE_NOTIFIER_H_
|
26
|
-
#define _PASSENGER_CHANGE_NOTIFIER_H_
|
27
|
-
|
28
|
-
#include <boost/function.hpp>
|
29
|
-
#include <boost/shared_ptr.hpp>
|
30
|
-
#include <string>
|
31
|
-
#include <ev++.h>
|
32
|
-
#include "DataStoreId.h"
|
33
|
-
#include "../EventedClient.h"
|
34
|
-
#include "../FileDescriptor.h"
|
35
|
-
#include "../StaticString.h"
|
36
|
-
|
37
|
-
namespace Passenger {
|
38
|
-
|
39
|
-
using namespace std;
|
40
|
-
using namespace boost;
|
41
|
-
|
42
|
-
|
43
|
-
class ChangeNotifier {
|
44
|
-
public:
|
45
|
-
typedef function<string (const StaticString &groupName, const StaticString &nodeName,
|
46
|
-
const StaticString &category)> GetLastPosFunction;
|
47
|
-
|
48
|
-
GetLastPosFunction getLastPos;
|
49
|
-
|
50
|
-
ChangeNotifier(struct ev_loop *_loop) { }
|
51
|
-
virtual ~ChangeNotifier() { }
|
52
|
-
|
53
|
-
virtual void addClient(const FileDescriptor &fd) { }
|
54
|
-
|
55
|
-
virtual void changed(const DataStoreId &dataStoreId) { }
|
56
|
-
};
|
57
|
-
|
58
|
-
typedef shared_ptr<ChangeNotifier> ChangeNotifierPtr;
|
59
|
-
|
60
|
-
|
61
|
-
} // namespace Passenger
|
62
|
-
|
63
|
-
#endif /* _PASSENGER_CHANGE_NOTIFIER_H_ */
|