cloudcms-server 4.0.0-beta.15 → 4.0.0-beta.17
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/middleware/awareness/plugins/editorial.js +50 -0
- package/middleware/virtual-config/virtual-config.js +1 -1
- package/package.json +1 -1
- package/server/index.js +50 -16
- package/util/cloudcms.js +41 -26
- package/util/request.js +4 -1
- package/util/workqueue.js +71 -60
|
@@ -21,6 +21,10 @@ exports.bindSocket = function(socket, provider, io)
|
|
|
21
21
|
commitEditorialWorkspace(socket, provider, sessionKey, repositoryId, branchId, callback);
|
|
22
22
|
});
|
|
23
23
|
|
|
24
|
+
socket.on("touchEditorialWorkspace", function(sessionKey, repositoryId, branchId, callback) {
|
|
25
|
+
touchEditorialWorkspace(socket, provider, sessionKey, repositoryId, branchId, callback);
|
|
26
|
+
});
|
|
27
|
+
|
|
24
28
|
socket.on("editorialWorkspaceInfo", function(sessionKey, repositoryId, branchId, callback) {
|
|
25
29
|
editorialWorkspaceInfo(socket, provider, sessionKey, repositoryId, branchId, callback);
|
|
26
30
|
});
|
|
@@ -219,6 +223,52 @@ exports.bindSocket = function(socket, provider, io)
|
|
|
219
223
|
});
|
|
220
224
|
};
|
|
221
225
|
|
|
226
|
+
/**
|
|
227
|
+
* Touches an editorial workspace.
|
|
228
|
+
*
|
|
229
|
+
* This is a "keep alive" call to prevent a workspace from being cleaned up while it is being
|
|
230
|
+
* worked on.
|
|
231
|
+
*
|
|
232
|
+
* @param socket
|
|
233
|
+
* @param provider
|
|
234
|
+
* @param sessionKey
|
|
235
|
+
* @param repositoryId
|
|
236
|
+
* @param branchId
|
|
237
|
+
* @param callback
|
|
238
|
+
*/
|
|
239
|
+
var touchEditorialWorkspace = function(socket, provider, sessionKey, repositoryId, branchId, callback)
|
|
240
|
+
{
|
|
241
|
+
var URL = util.asURL(process.env.GITANA_PROXY_SCHEME, process.env.GITANA_PROXY_HOST, process.env.GITANA_PROXY_PORT, process.env.GITANA_PROXY_PATH) + "/oneteam/editorial/workspace/touch";
|
|
242
|
+
|
|
243
|
+
var json = {};
|
|
244
|
+
json.repositoryId = repositoryId;
|
|
245
|
+
json.branchId = branchId;
|
|
246
|
+
json.key = sessionKey;
|
|
247
|
+
|
|
248
|
+
var headers = {};
|
|
249
|
+
var gitanaTicket = extractTicket(socket);
|
|
250
|
+
if (gitanaTicket)
|
|
251
|
+
{
|
|
252
|
+
headers["GITANA_TICKET"] = gitanaTicket;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
request({
|
|
256
|
+
"method": "POST",
|
|
257
|
+
"url": URL,
|
|
258
|
+
"qs": {},
|
|
259
|
+
"json": json,
|
|
260
|
+
"headers": headers,
|
|
261
|
+
"timeout": process.defaultHttpTimeoutMs
|
|
262
|
+
}, function(err, response, json) {
|
|
263
|
+
|
|
264
|
+
if (err || (json && json.error)) {
|
|
265
|
+
return callback(err);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
callback(null, json);
|
|
269
|
+
});
|
|
270
|
+
};
|
|
271
|
+
|
|
222
272
|
var extractTicket = function(socket)
|
|
223
273
|
{
|
|
224
274
|
var ticket = null;
|
|
@@ -12,7 +12,7 @@ var workQueueFactory = require("../../util/workqueue");
|
|
|
12
12
|
exports = module.exports = function()
|
|
13
13
|
{
|
|
14
14
|
// ensures that we only load 2 virtual config at a time
|
|
15
|
-
var enqueueLoadVirtualConfig = workQueueFactory(2);
|
|
15
|
+
var enqueueLoadVirtualConfig = workQueueFactory("loadVirtualConfigQueue", 2);
|
|
16
16
|
|
|
17
17
|
var SENTINEL_NOT_FOUND_VALUE = "null";
|
|
18
18
|
var BLACKLIST_TTL_SECONDS = 60 * 60 * 24 * 30; // 30 days
|
package/package.json
CHANGED
package/server/index.js
CHANGED
|
@@ -586,12 +586,55 @@ var _start = function(overrides, callback) {
|
|
|
586
586
|
if (!process.env.CLOUDCMS_STANDALONE_HOST) {
|
|
587
587
|
process.env.CLOUDCMS_STANDALONE_HOST = "local";
|
|
588
588
|
}
|
|
589
|
-
|
|
590
|
-
|
|
589
|
+
|
|
590
|
+
// http timeout
|
|
591
|
+
// default http timeout (2 minutes)
|
|
592
|
+
process.defaultHttpTimeoutMs = 2 * 60 * 1000;
|
|
593
|
+
if (process.env.DEFAULT_HTTP_TIMEOUT_MS)
|
|
594
|
+
{
|
|
595
|
+
try {
|
|
596
|
+
process.defaultHttpTimeoutMs = parseInt(process.env.DEFAULT_HTTP_TIMEOUT_MS);
|
|
597
|
+
} catch (e) { }
|
|
598
|
+
}
|
|
599
|
+
else if (process.configuration.timeout)
|
|
600
|
+
{
|
|
601
|
+
process.defaultHttpTimeoutMs = process.configuration.timeout;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
// socket keep alive (3 minutes)
|
|
605
|
+
process.defaultKeepAliveMs = (3 * 60 * 1000);
|
|
606
|
+
if (process.env.DEFAULT_KEEP_ALIVE_MS)
|
|
607
|
+
{
|
|
608
|
+
try {
|
|
609
|
+
process.defaultKeepAliveMs = parseInt(process.env.DEFAULT_KEEP_ALIVE_MS);
|
|
610
|
+
} catch (e) { }
|
|
611
|
+
}
|
|
612
|
+
else if (process.configuration.keepAliveMs)
|
|
613
|
+
{
|
|
614
|
+
process.defaultKeepAliveMs = process.configuration.keepAliveMs;
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
|
|
618
|
+
///////////////////////
|
|
619
|
+
// auto-configuration for HTTP
|
|
620
|
+
///////////////////////
|
|
621
|
+
|
|
622
|
+
if (!process.configuration.http) {
|
|
623
|
+
process.configuration.http = {};
|
|
624
|
+
}
|
|
625
|
+
process.configuration.http.keepAliveTimeout = process.defaultKeepAliveMs;
|
|
626
|
+
process.configuration.http.requestTimeout = process.defaultKeepAliveMs;
|
|
627
|
+
|
|
628
|
+
///////////////////////
|
|
591
629
|
// auto-configuration for HTTPS
|
|
630
|
+
///////////////////////
|
|
631
|
+
|
|
592
632
|
if (!process.configuration.https) {
|
|
593
633
|
process.configuration.https = {};
|
|
594
634
|
}
|
|
635
|
+
process.configuration.https.keepAliveTimeout = process.defaultKeepAliveMs;
|
|
636
|
+
process.configuration.https.requestTimeout = process.defaultKeepAliveMs;
|
|
637
|
+
|
|
595
638
|
if (process.env.CLOUDCMS_HTTPS) {
|
|
596
639
|
process.configuration.https = JSON.parse(process.env.CLOUDCMS_HTTPS);
|
|
597
640
|
}
|
|
@@ -614,12 +657,6 @@ var _start = function(overrides, callback) {
|
|
|
614
657
|
process.configuration.https.ca = [ fs.readFileSync(process.env.CLOUDCMS_HTTPS_CA_FILEPATH) ];
|
|
615
658
|
}
|
|
616
659
|
|
|
617
|
-
// if https config is empty, remove it
|
|
618
|
-
if (Object.keys(process.configuration.https).length === 0) {
|
|
619
|
-
delete process.configuration.https;
|
|
620
|
-
}
|
|
621
|
-
|
|
622
|
-
|
|
623
660
|
// auto configuration of session store
|
|
624
661
|
if (!process.configuration.session) {
|
|
625
662
|
process.configuration.session = {};
|
|
@@ -1214,20 +1251,17 @@ var createHttpServer = function(app, done)
|
|
|
1214
1251
|
else
|
|
1215
1252
|
{
|
|
1216
1253
|
// legacy
|
|
1217
|
-
httpServer = http.Server(app);
|
|
1254
|
+
//httpServer = http.Server(app);
|
|
1255
|
+
httpServer = http.createServer(process.configuration.http, app);
|
|
1218
1256
|
}
|
|
1219
1257
|
|
|
1220
|
-
//
|
|
1221
|
-
|
|
1222
|
-
if (process.configuration && process.configuration.timeout)
|
|
1223
|
-
{
|
|
1224
|
-
requestTimeout = process.configuration.timeout;
|
|
1225
|
-
}
|
|
1226
|
-
httpServer.setTimeout(requestTimeout, function(socket) {
|
|
1258
|
+
// socket timeout
|
|
1259
|
+
httpServer.setTimeout(process.defaultHttpTimeoutMs, function(socket) {
|
|
1227
1260
|
try { socket.end(); } catch (e) { }
|
|
1228
1261
|
try { socket.destroy(); } catch (e) { }
|
|
1229
1262
|
});
|
|
1230
1263
|
|
|
1264
|
+
|
|
1231
1265
|
var c = 0;
|
|
1232
1266
|
|
|
1233
1267
|
// socket
|
package/util/cloudcms.js
CHANGED
|
@@ -11,8 +11,8 @@ var workQueueFactory = require("./workqueue");
|
|
|
11
11
|
|
|
12
12
|
exports = module.exports = function()
|
|
13
13
|
{
|
|
14
|
-
// ensures that we only load
|
|
15
|
-
var previewQueueFn = workQueueFactory(
|
|
14
|
+
// ensures that we only load 5 preview icons at a time
|
|
15
|
+
var previewQueueFn = workQueueFactory("previewQueue", 5, false);
|
|
16
16
|
|
|
17
17
|
var toCacheFilePath = function(filePath)
|
|
18
18
|
{
|
|
@@ -356,7 +356,8 @@ exports = module.exports = function()
|
|
|
356
356
|
});
|
|
357
357
|
}
|
|
358
358
|
|
|
359
|
-
var failFast = function(contentStore, filePath, cb)
|
|
359
|
+
var failFast = function(contentStore, filePath, cb)
|
|
360
|
+
{
|
|
360
361
|
var triggered = false;
|
|
361
362
|
|
|
362
363
|
return function(tempStream, err)
|
|
@@ -383,7 +384,7 @@ exports = module.exports = function()
|
|
|
383
384
|
contentStore.writeStream(filePath, function(err, tempStream) {
|
|
384
385
|
|
|
385
386
|
if (err) {
|
|
386
|
-
return failFast(tempStream, err);
|
|
387
|
+
return failFast(tempStream, err, cb);
|
|
387
388
|
}
|
|
388
389
|
|
|
389
390
|
var cacheFilePath = toCacheFilePath(filePath);
|
|
@@ -406,9 +407,10 @@ exports = module.exports = function()
|
|
|
406
407
|
"method": "GET",
|
|
407
408
|
"url": URL,
|
|
408
409
|
"qs": {},
|
|
410
|
+
"timeout": 3000,
|
|
409
411
|
"headers": headers,
|
|
410
412
|
"responseType": "stream"
|
|
411
|
-
}, function(err, response) {
|
|
413
|
+
}, function(err, response, stream) {
|
|
412
414
|
|
|
413
415
|
if (err) {
|
|
414
416
|
closeWriteStream(tempStream);
|
|
@@ -417,34 +419,34 @@ exports = module.exports = function()
|
|
|
417
419
|
|
|
418
420
|
if (response.status >= 200 && response.status <= 204)
|
|
419
421
|
{
|
|
420
|
-
|
|
421
|
-
|
|
422
|
+
var handle = function (err) {
|
|
423
|
+
|
|
422
424
|
if (err) {
|
|
423
425
|
// some went wrong at disk io level?
|
|
424
|
-
return failFast(tempStream, err);
|
|
426
|
+
return failFast(tempStream, err, cb);
|
|
425
427
|
}
|
|
426
|
-
|
|
428
|
+
|
|
427
429
|
contentStore.existsFile(filePath, function (exists) {
|
|
428
|
-
|
|
430
|
+
|
|
429
431
|
if (exists) {
|
|
430
|
-
|
|
432
|
+
|
|
431
433
|
// write cache file
|
|
432
434
|
var cacheInfo = buildCacheInfo(response);
|
|
433
435
|
if (!cacheInfo) {
|
|
434
436
|
return cb(null, filePath, null);
|
|
435
437
|
}
|
|
436
|
-
|
|
438
|
+
|
|
437
439
|
contentStore.writeFile(cacheFilePath, JSON.stringify(cacheInfo, null, " "), function (err) {
|
|
438
|
-
|
|
440
|
+
|
|
439
441
|
if (err) {
|
|
440
442
|
// failed to write cache file, thus the whole thing is invalid
|
|
441
443
|
return safeRemove(contentStore, cacheFilePath, function () {
|
|
442
444
|
failFast(tempStream, {
|
|
443
445
|
"message": "Failed to write cache file: " + cacheFilePath + ", err: " + JSON.stringify(err)
|
|
444
|
-
});
|
|
446
|
+
}, cb);
|
|
445
447
|
});
|
|
446
448
|
}
|
|
447
|
-
|
|
449
|
+
|
|
448
450
|
cb(null, filePath, cacheInfo);
|
|
449
451
|
});
|
|
450
452
|
} else {
|
|
@@ -453,13 +455,27 @@ exports = module.exports = function()
|
|
|
453
455
|
safeRemove(contentStore, cacheFilePath, function () {
|
|
454
456
|
failFast(tempStream, {
|
|
455
457
|
"message": "Failed to verify written cached file: " + filePath
|
|
456
|
-
});
|
|
458
|
+
}, cb);
|
|
457
459
|
});
|
|
458
460
|
}
|
|
459
461
|
});
|
|
460
|
-
|
|
462
|
+
};
|
|
463
|
+
|
|
464
|
+
// stream.on("end", function() {
|
|
465
|
+
// console.log("g1");
|
|
466
|
+
// });
|
|
467
|
+
// stream.on("finish", function() {
|
|
468
|
+
// console.log("g2");
|
|
469
|
+
// });
|
|
470
|
+
stream.on("close", handle);
|
|
471
|
+
|
|
472
|
+
stream.pipe(tempStream).on("close", handle).on("end", function() {
|
|
473
|
+
//console.log("a4");
|
|
474
|
+
}).on("finish", function() {
|
|
475
|
+
//console.log("a5");
|
|
461
476
|
}).on("error", function (err) {
|
|
462
|
-
|
|
477
|
+
console.log("a3");
|
|
478
|
+
failFast(tempStream, err, cb);
|
|
463
479
|
});
|
|
464
480
|
}
|
|
465
481
|
else
|
|
@@ -467,13 +483,13 @@ exports = module.exports = function()
|
|
|
467
483
|
// some kind of http error (usually permission denied or invalid_token)
|
|
468
484
|
|
|
469
485
|
var body = "";
|
|
470
|
-
|
|
471
|
-
|
|
486
|
+
|
|
487
|
+
stream.on('data', function (chunk) {
|
|
472
488
|
body += chunk;
|
|
473
489
|
});
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
490
|
+
|
|
491
|
+
stream.on('end', function () {
|
|
492
|
+
|
|
477
493
|
var afterCleanup = function () {
|
|
478
494
|
|
|
479
495
|
// see if it is "invalid_token"
|
|
@@ -515,11 +531,10 @@ exports = module.exports = function()
|
|
|
515
531
|
});
|
|
516
532
|
});
|
|
517
533
|
});
|
|
518
|
-
|
|
519
534
|
}
|
|
520
535
|
});
|
|
521
536
|
// }).on('error', function (e) {
|
|
522
|
-
// failFast(tempStream, e);
|
|
537
|
+
// failFast(tempStream, e, cb);
|
|
523
538
|
//
|
|
524
539
|
// }).on('end', function (e) {
|
|
525
540
|
//
|
|
@@ -532,7 +547,7 @@ exports = module.exports = function()
|
|
|
532
547
|
process.log("Temp stream errored out");
|
|
533
548
|
process.log(e);
|
|
534
549
|
|
|
535
|
-
failFast(tempStream, e);
|
|
550
|
+
failFast(tempStream, e, cb);
|
|
536
551
|
|
|
537
552
|
// ensure stream is closed
|
|
538
553
|
//closeWriteStream(tempStream);
|
package/util/request.js
CHANGED
|
@@ -103,7 +103,6 @@ module.exports = function(config, callback)
|
|
|
103
103
|
requestConfig.responseType = config.responseType;
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
-
|
|
107
106
|
/*
|
|
108
107
|
if (requestConfig.url.toLowerCase().indexOf("https:") > -1)
|
|
109
108
|
{
|
|
@@ -114,6 +113,10 @@ module.exports = function(config, callback)
|
|
|
114
113
|
requestConfig.httpAgent = http.globalAgent;
|
|
115
114
|
}
|
|
116
115
|
*/
|
|
116
|
+
|
|
117
|
+
if (config.timeout) {
|
|
118
|
+
requestConfig.timeout = config.timeout;
|
|
119
|
+
}
|
|
117
120
|
|
|
118
121
|
return axios.request(requestConfig).then(function(response) {
|
|
119
122
|
callback(null, response, response.data);
|
package/util/workqueue.js
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
|
|
1
|
+
var util = require("./util");
|
|
2
|
+
|
|
3
|
+
module.exports = function(name, maxSize, debug)
|
|
2
4
|
{
|
|
3
5
|
if (!maxSize) {
|
|
4
6
|
maxSize = 3;
|
|
5
7
|
}
|
|
6
8
|
|
|
7
|
-
var blockExecution = false;
|
|
8
|
-
|
|
9
9
|
var pendingWorkQueue = [];
|
|
10
10
|
var activeCount = 0;
|
|
11
11
|
|
|
12
|
-
var
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
if (blockExecution)
|
|
12
|
+
var debugLog = function(text)
|
|
13
|
+
{
|
|
14
|
+
if (debug)
|
|
16
15
|
{
|
|
17
|
-
|
|
16
|
+
console.log("[WORKQUEUE: " + name + "] " + text);
|
|
18
17
|
}
|
|
18
|
+
}
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
var dispatcherFn = function () {
|
|
21
21
|
|
|
22
22
|
// add as many pending work items as we can, loop until full or no more pending
|
|
23
23
|
var process = true;
|
|
@@ -28,73 +28,84 @@ module.exports = function(maxSize)
|
|
|
28
28
|
{
|
|
29
29
|
process = false;
|
|
30
30
|
}
|
|
31
|
-
|
|
32
|
-
// if we're full, bail
|
|
33
|
-
if (activeCount >= maxSize)
|
|
34
|
-
{
|
|
35
|
-
process = false;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
if (process)
|
|
31
|
+
else
|
|
39
32
|
{
|
|
40
|
-
//
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
//
|
|
44
|
-
|
|
45
|
-
//
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
33
|
+
// var ids = [];
|
|
34
|
+
// for (var z = 0; z < pendingWorkQueue.length; z++)
|
|
35
|
+
// {
|
|
36
|
+
// ids.push(pendingWorkQueue[z].id);
|
|
37
|
+
// }
|
|
38
|
+
//
|
|
39
|
+
// debugLog("Dispatcher top, queue: " + ids.join(","));
|
|
40
|
+
|
|
41
|
+
//debugLog("dispatcher, pending: " + pendingWorkQueue.length + ", actives: " + activeCount + "]");
|
|
42
|
+
|
|
43
|
+
// if we're full, bail
|
|
44
|
+
if (activeCount >= maxSize)
|
|
45
|
+
{
|
|
46
|
+
process = false;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (process)
|
|
50
|
+
{
|
|
51
|
+
// increment active count
|
|
52
|
+
activeCount++;
|
|
53
|
+
|
|
54
|
+
// define execution function and splice/bind to 0th element from pending list
|
|
55
|
+
var executionFn = function(work) {
|
|
56
|
+
return function() {
|
|
57
|
+
var workFn = work.workFn;
|
|
58
|
+
var callbackFn = work.callbackFn;
|
|
59
|
+
|
|
60
|
+
debugLog("Start: " + work.id + ", queue: " + pendingWorkQueue.length + ", actives: " + activeCount);
|
|
61
|
+
|
|
62
|
+
workFn(function(err, obj1, obj2) {
|
|
63
|
+
|
|
64
|
+
// fire optional callback
|
|
65
|
+
if (callbackFn) {
|
|
66
|
+
window.setTimeout(function() {
|
|
67
|
+
callbackFn(err, obj1, obj2);
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// decrement active count
|
|
72
|
+
activeCount--;
|
|
73
|
+
|
|
74
|
+
debugLog("Complete: " + work.id + ", queue: " + pendingWorkQueue.length + ", actives: " + activeCount);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
};
|
|
78
|
+
}(pendingWorkQueue.splice(0, 1)[0]);
|
|
79
|
+
|
|
80
|
+
// execute on timeout
|
|
81
|
+
window.setTimeout(executionFn);
|
|
82
|
+
}
|
|
77
83
|
}
|
|
78
84
|
|
|
79
85
|
} while (process);
|
|
80
86
|
|
|
81
|
-
|
|
87
|
+
// run again on a brief timeout
|
|
88
|
+
window.setTimeout(dispatcherFn, 50);
|
|
82
89
|
};
|
|
83
90
|
|
|
91
|
+
// launch dispatcher
|
|
92
|
+
window.setTimeout(dispatcherFn);
|
|
93
|
+
|
|
94
|
+
// hand back a function to register work onto the queue
|
|
84
95
|
return function(workFn, callbackFn) {
|
|
85
96
|
|
|
86
|
-
var
|
|
97
|
+
var work = {
|
|
98
|
+
"id": util.guid(),
|
|
87
99
|
"workFn": workFn
|
|
88
100
|
};
|
|
89
101
|
|
|
90
102
|
if (callbackFn) {
|
|
91
|
-
|
|
103
|
+
work.callbackFn = callbackFn;
|
|
92
104
|
}
|
|
93
105
|
|
|
94
|
-
pendingWorkQueue.push(
|
|
106
|
+
pendingWorkQueue.push(work);
|
|
95
107
|
|
|
96
|
-
//
|
|
97
|
-
window.setTimeout(processWork);
|
|
108
|
+
//debugLog("Added to pending queue, id: " + work.id + ", pending: " + pendingWorkQueue.length);
|
|
98
109
|
};
|
|
99
110
|
|
|
100
111
|
};
|