cloudcms-server 3.2.316 → 3.2.318
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/locks/providers/memory.js +1 -1
- package/middleware/virtual-config/virtual-config.js +218 -199
- package/package.json +1 -1
- package/server/index.js +30 -0
- package/temp/clusterlock/index.js +5 -1
- package/util/loaders.js +5 -0
- package/util/workqueue.js +80 -0
|
@@ -23,10 +23,10 @@ exports = module.exports = function(lockConfig)
|
|
|
23
23
|
lock.acquire(key, function(releaseCallbackFn) {
|
|
24
24
|
fn(null, releaseCallbackFn);
|
|
25
25
|
}, function(err, ret) {
|
|
26
|
-
// lock was released
|
|
27
26
|
if (err) {
|
|
28
27
|
console.error("Memory Lock heard error: ", err, " return value: ", ret);
|
|
29
28
|
}
|
|
29
|
+
fn(err);
|
|
30
30
|
});
|
|
31
31
|
};
|
|
32
32
|
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
var util = require("../../util/util");
|
|
2
2
|
|
|
3
|
+
var workQueueFactory = require("../../util/workqueue");
|
|
4
|
+
|
|
3
5
|
/**
|
|
4
6
|
* Retrieves virtual driver configuration for hosts from Cloud CMS.
|
|
5
7
|
*
|
|
@@ -7,7 +9,11 @@ var util = require("../../util/util");
|
|
|
7
9
|
*/
|
|
8
10
|
exports = module.exports = function()
|
|
9
11
|
{
|
|
12
|
+
// ensures that we only load 2 virtual config at a time
|
|
13
|
+
var enqueueLoadVirtualConfig = workQueueFactory(2);
|
|
14
|
+
|
|
10
15
|
var SENTINEL_NOT_FOUND_VALUE = "null";
|
|
16
|
+
var BLACKLIST_TTL_SECONDS = 60 * 60 * 24 * 30; // 30 days
|
|
11
17
|
|
|
12
18
|
var VIRTUAL_DRIVER_CACHE_KEY = "virtualdriver";
|
|
13
19
|
|
|
@@ -53,98 +59,96 @@ exports = module.exports = function()
|
|
|
53
59
|
{
|
|
54
60
|
var configuration = process.configuration;
|
|
55
61
|
|
|
56
|
-
if (configuration.virtualDriver
|
|
62
|
+
if (!configuration.virtualDriver || !configuration.virtualDriver.enabled)
|
|
57
63
|
{
|
|
58
|
-
|
|
64
|
+
return callback();
|
|
65
|
+
}
|
|
59
66
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
67
|
+
// no appkey, cannot load
|
|
68
|
+
if (!configuration.virtualDriver.appKey)
|
|
69
|
+
{
|
|
70
|
+
return callback();
|
|
71
|
+
}
|
|
64
72
|
|
|
65
|
-
|
|
66
|
-
if (!configuration.virtualDriver.appKey)
|
|
67
|
-
{
|
|
68
|
-
return callback();
|
|
69
|
-
}
|
|
73
|
+
connectAsVirtualDriver(function(err, gitana) {
|
|
70
74
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
+
if (err)
|
|
76
|
+
{
|
|
77
|
+
return callback(err);
|
|
78
|
+
}
|
|
75
79
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
+
// Basic Authentication request back to server
|
|
81
|
+
var qs = {};
|
|
82
|
+
qs.h = host;
|
|
83
|
+
qs.a = configuration.virtualDriver.appKey;
|
|
80
84
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
URL += "/virtual/driver/config";
|
|
86
|
-
var requestConfig = {
|
|
87
|
-
"url": URL,
|
|
88
|
-
"qs": qs
|
|
89
|
-
};
|
|
85
|
+
if (configuration.virtualDriver && configuration.virtualDriver.webhost)
|
|
86
|
+
{
|
|
87
|
+
qs.w = configuration.virtualDriver.webhost;
|
|
88
|
+
}
|
|
90
89
|
|
|
91
|
-
|
|
90
|
+
var URL = configuration.virtualDriver.baseURL;
|
|
91
|
+
if (!URL) {
|
|
92
|
+
URL = util.asURL(process.env.GITANA_PROXY_SCHEME, process.env.GITANA_PROXY_HOST, process.env.GITANA_PROXY_PORT, process.env.GITANA_PROXY_PATH);
|
|
93
|
+
}
|
|
94
|
+
URL += "/virtual/driver/config";
|
|
95
|
+
var requestConfig = {
|
|
96
|
+
"url": URL,
|
|
97
|
+
"qs": qs
|
|
98
|
+
};
|
|
92
99
|
|
|
93
|
-
|
|
94
|
-
{
|
|
95
|
-
var config = body.config;
|
|
96
|
-
if (!config)
|
|
97
|
-
{
|
|
98
|
-
// nothing found
|
|
99
|
-
callback();
|
|
100
|
-
}
|
|
101
|
-
else
|
|
102
|
-
{
|
|
103
|
-
// make sure we update baseURL
|
|
104
|
-
config.baseURL = configuration.virtualDriver.baseURL;
|
|
100
|
+
util.retryGitanaRequest(logMethod, gitana, requestConfig, 2, function(err, response, body) {
|
|
105
101
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
102
|
+
if (response && response.status === 200 && body)
|
|
103
|
+
{
|
|
104
|
+
var config = body.config;
|
|
105
|
+
if (!config)
|
|
106
|
+
{
|
|
107
|
+
// nothing found
|
|
108
|
+
callback();
|
|
109
109
|
}
|
|
110
110
|
else
|
|
111
111
|
{
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
{
|
|
115
|
-
logMethod("Response status code: " + response.status);
|
|
116
|
-
}
|
|
117
|
-
if (err) {
|
|
118
|
-
logMethod("Err: " + JSON.stringify(err));
|
|
119
|
-
}
|
|
120
|
-
if (body) {
|
|
121
|
-
logMethod("Body: " + body);
|
|
122
|
-
}
|
|
123
|
-
var message = null;
|
|
124
|
-
if (body) {
|
|
125
|
-
message = JSON.stringify(body);
|
|
126
|
-
}
|
|
127
|
-
if (!message) {
|
|
128
|
-
message = "Unable to load virtual driver configuration";
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// force disconnect of virtual driver so that it has to log in again
|
|
132
|
-
// this prevents the attempt to use the refresh token
|
|
133
|
-
disconnectVirtualDriver();
|
|
112
|
+
// make sure we update baseURL
|
|
113
|
+
config.baseURL = configuration.virtualDriver.baseURL;
|
|
134
114
|
|
|
135
|
-
//
|
|
136
|
-
callback(
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
115
|
+
// hand back
|
|
116
|
+
callback(null, config);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
else
|
|
120
|
+
{
|
|
121
|
+
logMethod("Load virtual driver config failed");
|
|
122
|
+
if (response && response.status)
|
|
123
|
+
{
|
|
124
|
+
logMethod("Response status code: " + response.status);
|
|
140
125
|
}
|
|
141
|
-
|
|
126
|
+
if (err) {
|
|
127
|
+
logMethod("Err: " + JSON.stringify(err));
|
|
128
|
+
}
|
|
129
|
+
if (body) {
|
|
130
|
+
logMethod("Body: " + body);
|
|
131
|
+
}
|
|
132
|
+
var message = null;
|
|
133
|
+
if (body) {
|
|
134
|
+
message = JSON.stringify(body);
|
|
135
|
+
}
|
|
136
|
+
if (!message) {
|
|
137
|
+
message = "Unable to load virtual driver configuration";
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// force disconnect of virtual driver so that it has to log in again
|
|
141
|
+
// this prevents the attempt to use the refresh token
|
|
142
|
+
disconnectVirtualDriver();
|
|
143
|
+
|
|
144
|
+
// fire callback
|
|
145
|
+
callback({
|
|
146
|
+
"message": message,
|
|
147
|
+
"err": err
|
|
148
|
+
});
|
|
149
|
+
}
|
|
142
150
|
});
|
|
143
|
-
}
|
|
144
|
-
else
|
|
145
|
-
{
|
|
146
|
-
callback();
|
|
147
|
-
}
|
|
151
|
+
});
|
|
148
152
|
};
|
|
149
153
|
|
|
150
154
|
var r = {};
|
|
@@ -158,166 +162,171 @@ exports = module.exports = function()
|
|
|
158
162
|
|
|
159
163
|
var VCSENTINEL_CACHE_KEY = "vcSentinelFailed-" + host;
|
|
160
164
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
var loadFromRemote = function(finishedLoading) {
|
|
164
|
-
|
|
165
|
-
// check cache to see if we already tried to load this in the past few minutes and were sorely disappointed
|
|
166
|
-
process.cache.read(VCSENTINEL_CACHE_KEY, function (err, doesNotExist) {
|
|
167
|
-
|
|
168
|
-
if (doesNotExist) {
|
|
169
|
-
return finishedLoading({
|
|
170
|
-
"message": "No virtual config found for host (from previous attempt)"
|
|
171
|
-
}, null, true);
|
|
172
|
-
}
|
|
165
|
+
// so that only N number of virtual configs are loaded at a time
|
|
166
|
+
enqueueLoadVirtualConfig(function(host, rootStore, logMethod, callback) {
|
|
173
167
|
|
|
174
|
-
|
|
175
|
-
loadConfigForVirtualHost(host, logMethod, function (err, virtualConfig) {
|
|
168
|
+
rootStore.existsFile("gitana.json", function(exists) {
|
|
176
169
|
|
|
177
|
-
|
|
178
|
-
{
|
|
179
|
-
// something failed, perhaps a network issue
|
|
180
|
-
// don't store anything
|
|
181
|
-
return finishedLoading(err);
|
|
182
|
-
}
|
|
170
|
+
var loadFromRemote = function(finishedLoading) {
|
|
183
171
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
// mark that it failed (30 minute TTL)
|
|
187
|
-
return process.cache.write(VCSENTINEL_CACHE_KEY, true, 30 * 60, function() {
|
|
188
|
-
finishedLoading({
|
|
189
|
-
"message": "No virtual config found for host: " + host
|
|
190
|
-
});
|
|
191
|
-
});
|
|
192
|
-
}
|
|
172
|
+
// check cache to see if we already tried to load this in the past few minutes and were sorely disappointed
|
|
173
|
+
process.cache.read(VCSENTINEL_CACHE_KEY, function (err, doesNotExist) {
|
|
193
174
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
if (virtualConfig.clientSecret) {
|
|
199
|
-
gitanaJson.clientSecret = virtualConfig.clientSecret;
|
|
175
|
+
if (doesNotExist) {
|
|
176
|
+
return finishedLoading({
|
|
177
|
+
"message": "No virtual config found for host (from previous attempt)"
|
|
178
|
+
}, null, true);
|
|
200
179
|
}
|
|
201
|
-
if (virtualConfig.username) {
|
|
202
|
-
gitanaJson.username = virtualConfig.username;
|
|
203
|
-
}
|
|
204
|
-
if (virtualConfig.password) {
|
|
205
|
-
gitanaJson.password = virtualConfig.password;
|
|
206
|
-
}
|
|
207
|
-
if (virtualConfig.application) {
|
|
208
|
-
gitanaJson.application = virtualConfig.application;
|
|
209
|
-
}
|
|
210
|
-
if (virtualConfig.baseURL) {
|
|
211
|
-
gitanaJson.baseURL = virtualConfig.baseURL;
|
|
212
|
-
}
|
|
213
|
-
if (!gitanaJson.baseURL)
|
|
214
|
-
{
|
|
215
|
-
gitanaJson.baseURL = util.cleanupURL(util.asURL(process.env.GITANA_PROXY_SCHEME, process.env.GITANA_PROXY_HOST, process.env.GITANA_PROXY_PORT, process.env.GITANA_PROXY_PATH));
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
// mark as retrieved from virtual driver
|
|
219
|
-
gitanaJson._virtual = true;
|
|
220
180
|
|
|
221
|
-
//
|
|
222
|
-
|
|
181
|
+
// load the gitana.json file from Cloud CMS
|
|
182
|
+
loadConfigForVirtualHost(host, logMethod, function (err, virtualConfig) {
|
|
223
183
|
|
|
224
|
-
// if we failed to write the file, then delete and call back with error
|
|
225
184
|
if (err)
|
|
226
185
|
{
|
|
227
|
-
|
|
228
|
-
|
|
186
|
+
// something failed, perhaps a network issue
|
|
187
|
+
// don't store anything
|
|
188
|
+
return finishedLoading(err);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (!virtualConfig)
|
|
192
|
+
{
|
|
193
|
+
// mark that it failed (30 minute TTL)
|
|
194
|
+
return process.cache.write(VCSENTINEL_CACHE_KEY, true, BLACKLIST_TTL_SECONDS, function() {
|
|
195
|
+
finishedLoading({
|
|
196
|
+
"message": "No virtual config found for host: " + host
|
|
197
|
+
});
|
|
229
198
|
});
|
|
230
199
|
}
|
|
231
200
|
|
|
232
|
-
//
|
|
233
|
-
|
|
234
|
-
|
|
201
|
+
// populate gitana.json
|
|
202
|
+
var gitanaJson = {
|
|
203
|
+
"clientKey": virtualConfig.clientKey
|
|
204
|
+
};
|
|
205
|
+
if (virtualConfig.clientSecret) {
|
|
206
|
+
gitanaJson.clientSecret = virtualConfig.clientSecret;
|
|
207
|
+
}
|
|
208
|
+
if (virtualConfig.username) {
|
|
209
|
+
gitanaJson.username = virtualConfig.username;
|
|
210
|
+
}
|
|
211
|
+
if (virtualConfig.password) {
|
|
212
|
+
gitanaJson.password = virtualConfig.password;
|
|
213
|
+
}
|
|
214
|
+
if (virtualConfig.application) {
|
|
215
|
+
gitanaJson.application = virtualConfig.application;
|
|
216
|
+
}
|
|
217
|
+
if (virtualConfig.baseURL) {
|
|
218
|
+
gitanaJson.baseURL = virtualConfig.baseURL;
|
|
219
|
+
}
|
|
220
|
+
if (!gitanaJson.baseURL)
|
|
221
|
+
{
|
|
222
|
+
gitanaJson.baseURL = util.cleanupURL(util.asURL(process.env.GITANA_PROXY_SCHEME, process.env.GITANA_PROXY_HOST, process.env.GITANA_PROXY_PORT, process.env.GITANA_PROXY_PATH));
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// mark as retrieved from virtual driver
|
|
226
|
+
gitanaJson._virtual = true;
|
|
227
|
+
|
|
228
|
+
// write the gitana.json file
|
|
229
|
+
rootStore.writeFile("gitana.json", JSON.stringify(gitanaJson, null, " "), function (err) {
|
|
235
230
|
|
|
236
|
-
// if we failed to
|
|
237
|
-
if (err
|
|
231
|
+
// if we failed to write the file, then delete and call back with error
|
|
232
|
+
if (err)
|
|
238
233
|
{
|
|
239
234
|
return rootStore.deleteFile("gitana.json", function() {
|
|
240
|
-
finishedLoading(
|
|
241
|
-
"message": "There was a problem writing the driver configuration file. Please reload."
|
|
242
|
-
});
|
|
235
|
+
finishedLoading(err);
|
|
243
236
|
});
|
|
244
237
|
}
|
|
245
238
|
|
|
246
|
-
|
|
239
|
+
// make sure the file wrote successfully
|
|
240
|
+
// check stats, ensure non-error and file size > 0
|
|
241
|
+
rootStore.fileStats("gitana.json", function(err, stats) {
|
|
242
|
+
|
|
243
|
+
// if we failed to read stats, then delete and call back with error
|
|
244
|
+
if (err || stats.size === 0)
|
|
245
|
+
{
|
|
246
|
+
return rootStore.deleteFile("gitana.json", function() {
|
|
247
|
+
finishedLoading({
|
|
248
|
+
"message": "There was a problem writing the driver configuration file. Please reload."
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
finishedLoading(null, gitanaJson);
|
|
254
|
+
});
|
|
247
255
|
});
|
|
248
256
|
});
|
|
249
257
|
});
|
|
250
|
-
}
|
|
251
|
-
};
|
|
252
|
-
|
|
253
|
-
if (exists)
|
|
254
|
-
{
|
|
255
|
-
// read gitana json and send back
|
|
256
|
-
rootStore.readFile("gitana.json", function(err, data) {
|
|
257
|
-
|
|
258
|
-
if (err)
|
|
259
|
-
{
|
|
260
|
-
return callback(err);
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
if (!data)
|
|
264
|
-
{
|
|
265
|
-
return callback({
|
|
266
|
-
"message": "The gitana.json data read from disk was null or empty"
|
|
267
|
-
})
|
|
268
|
-
}
|
|
258
|
+
};
|
|
269
259
|
|
|
270
|
-
|
|
271
|
-
|
|
260
|
+
if (exists)
|
|
261
|
+
{
|
|
262
|
+
// read gitana json and send back
|
|
263
|
+
rootStore.readFile("gitana.json", function(err, data) {
|
|
272
264
|
|
|
273
265
|
if (err)
|
|
274
266
|
{
|
|
275
267
|
return callback(err);
|
|
276
268
|
}
|
|
277
269
|
|
|
278
|
-
|
|
279
|
-
if (err || stats.size === 0)
|
|
270
|
+
if (!data)
|
|
280
271
|
{
|
|
281
|
-
return
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
});
|
|
285
|
-
});
|
|
272
|
+
return callback({
|
|
273
|
+
"message": "The gitana.json data read from disk was null or empty"
|
|
274
|
+
})
|
|
286
275
|
}
|
|
287
276
|
|
|
288
|
-
//
|
|
289
|
-
|
|
277
|
+
// make sure not size 0
|
|
278
|
+
rootStore.fileStats("gitana.json", function(err, stats) {
|
|
290
279
|
|
|
291
|
-
|
|
280
|
+
if (err)
|
|
281
|
+
{
|
|
282
|
+
return callback(err);
|
|
283
|
+
}
|
|
292
284
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
{
|
|
296
|
-
var newBaseURL = util.cleanupURL(gitanaJson.baseURL);
|
|
297
|
-
if (newBaseURL !== gitanaJson.baseURL)
|
|
285
|
+
// if we failed to read stats or file size 0, then delete and call back with error
|
|
286
|
+
if (err || stats.size === 0)
|
|
298
287
|
{
|
|
299
|
-
|
|
288
|
+
return rootStore.deleteFile("gitana.json", function() {
|
|
289
|
+
callback({
|
|
290
|
+
"message": "There was a problem writing the driver configuration file. Please reload."
|
|
291
|
+
});
|
|
292
|
+
});
|
|
293
|
+
}
|
|
300
294
|
|
|
301
|
-
|
|
295
|
+
// remove vcSentinel if it exists
|
|
296
|
+
process.cache.remove(VCSENTINEL_CACHE_KEY);
|
|
302
297
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
298
|
+
var gitanaJson = JSON.parse("" + data);
|
|
299
|
+
|
|
300
|
+
// auto-upgrade the host?
|
|
301
|
+
if (gitanaJson.baseURL)
|
|
302
|
+
{
|
|
303
|
+
var newBaseURL = util.cleanupURL(gitanaJson.baseURL);
|
|
304
|
+
if (newBaseURL !== gitanaJson.baseURL)
|
|
305
|
+
{
|
|
306
|
+
console.log("Auto-upgrade gitana.json from: " + gitanaJson.baseURL + ", to: " + newBaseURL);
|
|
307
|
+
|
|
308
|
+
gitanaJson.baseURL = newBaseURL;
|
|
309
|
+
|
|
310
|
+
// write the gitana.json file
|
|
311
|
+
rootStore.writeFile("gitana.json", JSON.stringify(gitanaJson, null, " "), function (err) {
|
|
312
|
+
// nada
|
|
313
|
+
});
|
|
314
|
+
}
|
|
307
315
|
}
|
|
308
|
-
}
|
|
309
316
|
|
|
310
|
-
|
|
311
|
-
|
|
317
|
+
// otherwise, fine!
|
|
318
|
+
callback(null, gitanaJson);
|
|
319
|
+
});
|
|
312
320
|
});
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
+
}
|
|
322
|
+
else
|
|
323
|
+
{
|
|
324
|
+
loadFromRemote(function(err, gitanaJson, doesNotExist) {
|
|
325
|
+
callback(err, gitanaJson, doesNotExist);
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
});
|
|
329
|
+
|
|
321
330
|
});
|
|
322
331
|
};
|
|
323
332
|
|
|
@@ -345,6 +354,16 @@ exports = module.exports = function()
|
|
|
345
354
|
{
|
|
346
355
|
if (doesNotExist)
|
|
347
356
|
{
|
|
357
|
+
// console.log("BLOCK, method: " + req.method + ", url: " + req.url);
|
|
358
|
+
// if (req.headers)
|
|
359
|
+
// {
|
|
360
|
+
// console.log(" -> headers: " + JSON.stringify(req.headers, null, 2));
|
|
361
|
+
// }
|
|
362
|
+
// if (req.query)
|
|
363
|
+
// {
|
|
364
|
+
// console.log(" -> query: " + JSON.stringify(req.query, null, 2));
|
|
365
|
+
// }
|
|
366
|
+
//
|
|
348
367
|
// are we being spoofed? kill the connection
|
|
349
368
|
res.blocked = true;
|
|
350
369
|
res.writeHead(503, { 'Content-Type': 'application/json' });
|
|
@@ -413,7 +432,7 @@ exports = module.exports = function()
|
|
|
413
432
|
|
|
414
433
|
// mark with sentinel (30 minutes)
|
|
415
434
|
req.log("[BLACKLIST] Adding: " + req.virtualHost);
|
|
416
|
-
process.driverConfigCache.write(req.virtualHost, SENTINEL_NOT_FOUND_VALUE,
|
|
435
|
+
process.driverConfigCache.write(req.virtualHost, SENTINEL_NOT_FOUND_VALUE, BLACKLIST_TTL_SECONDS, function (err) {
|
|
417
436
|
completionFunction(null, null, true);
|
|
418
437
|
});
|
|
419
438
|
});
|
package/package.json
CHANGED
package/server/index.js
CHANGED
|
@@ -992,6 +992,36 @@ var startServer = function(config, startServerFinishedFn)
|
|
|
992
992
|
|
|
993
993
|
next();
|
|
994
994
|
});
|
|
995
|
+
|
|
996
|
+
// kills immediately based on path, headers or other detections
|
|
997
|
+
app.use(function(req, res, next) {
|
|
998
|
+
|
|
999
|
+
var kill = false;
|
|
1000
|
+
if (req.path.endsWith("/env"))
|
|
1001
|
+
{
|
|
1002
|
+
kill = true;
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
if (kill)
|
|
1006
|
+
{
|
|
1007
|
+
// console.log("KILL, method: " + req.method + ", url: " + req.url);
|
|
1008
|
+
// if (req.headers)
|
|
1009
|
+
// {
|
|
1010
|
+
// console.log(" -> headers: " + JSON.stringify(req.headers, null, 2));
|
|
1011
|
+
// }
|
|
1012
|
+
// if (req.query)
|
|
1013
|
+
// {
|
|
1014
|
+
// console.log(" -> query: " + JSON.stringify(req.query, null, 2));
|
|
1015
|
+
// }
|
|
1016
|
+
//
|
|
1017
|
+
// are we being spoofed? kill the connection
|
|
1018
|
+
res.blocked = true;
|
|
1019
|
+
res.writeHead(503, { 'Content-Type': 'application/json' });
|
|
1020
|
+
return res.end(JSON.stringify({"error": true, "message": "Bad Request."}));
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
next();
|
|
1024
|
+
});
|
|
995
1025
|
|
|
996
1026
|
// common interceptors and config
|
|
997
1027
|
main.common1(app);
|
|
@@ -35,8 +35,12 @@ var _setup = function() {
|
|
|
35
35
|
};
|
|
36
36
|
|
|
37
37
|
_sendMessageToWorker(message);
|
|
38
|
+
}, function(err, ret) {
|
|
39
|
+
// lock was released
|
|
40
|
+
if (err) {
|
|
41
|
+
console.error("Cluster Lock heard error: ", err, " return value: ", ret);
|
|
42
|
+
}
|
|
38
43
|
});
|
|
39
|
-
|
|
40
44
|
};
|
|
41
45
|
|
|
42
46
|
var _release = function(message)
|
package/util/loaders.js
CHANGED
|
@@ -94,6 +94,11 @@ var exclusive = exports.exclusive = function(loader, key, timeout)
|
|
|
94
94
|
}, 0);
|
|
95
95
|
callback.call(this, err, value);
|
|
96
96
|
});
|
|
97
|
+
}, function(err, ret) {
|
|
98
|
+
if (err) {
|
|
99
|
+
console.error("Loaders async lock acquire heard error: ", err, " return value: ", ret);
|
|
100
|
+
}
|
|
101
|
+
callback.call(this, err, ret);
|
|
97
102
|
}, opts);
|
|
98
103
|
};
|
|
99
104
|
};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
var exports = module.exports;
|
|
2
|
+
|
|
3
|
+
exports = function(maxSize)
|
|
4
|
+
{
|
|
5
|
+
if (!maxSize) {
|
|
6
|
+
maxSize = 3;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
var blockExecution = false;
|
|
10
|
+
|
|
11
|
+
var pendingWorkFns = [];
|
|
12
|
+
var activeCount = 0;
|
|
13
|
+
|
|
14
|
+
var processWork = function () {
|
|
15
|
+
|
|
16
|
+
// if another "thread" is running the processor, don't bother
|
|
17
|
+
if (blockExecution)
|
|
18
|
+
{
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
blockExecution = true;
|
|
23
|
+
|
|
24
|
+
// add as many pending work items as we can, loop until full or no more pending
|
|
25
|
+
var process = true;
|
|
26
|
+
do
|
|
27
|
+
{
|
|
28
|
+
// if nothing to work on, bail
|
|
29
|
+
if (pendingWorkFns.length === 0)
|
|
30
|
+
{
|
|
31
|
+
process = false;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// if we're full, bail
|
|
35
|
+
if (activeCount >= maxSize)
|
|
36
|
+
{
|
|
37
|
+
process = false;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (process)
|
|
41
|
+
{
|
|
42
|
+
// increment active count
|
|
43
|
+
activeCount++;
|
|
44
|
+
|
|
45
|
+
//console.log("Active work items: " + activeCount);
|
|
46
|
+
|
|
47
|
+
// define execution function and splice/bind to 0th element from pending list
|
|
48
|
+
var executionFn = function(workFn) {
|
|
49
|
+
return function() {
|
|
50
|
+
workFn(function () {
|
|
51
|
+
|
|
52
|
+
// decrement active count
|
|
53
|
+
activeCount--;
|
|
54
|
+
|
|
55
|
+
//console.log("Active work items: " + activeCount);
|
|
56
|
+
|
|
57
|
+
// process more work on timeout
|
|
58
|
+
window.setTimeout(processWork);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
};
|
|
62
|
+
}(pendingWorkFns.splice(0, 1)[0]);
|
|
63
|
+
|
|
64
|
+
// execute on timeout
|
|
65
|
+
window.setTimeout(executionFn);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
} while (process);
|
|
69
|
+
|
|
70
|
+
blockExecution = false;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
return function(workFn) {
|
|
74
|
+
pendingWorkFns.push(workFn);
|
|
75
|
+
|
|
76
|
+
// execute on timeout
|
|
77
|
+
window.setTimeout(processWork);
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
};
|