cloudcms-server 0.9.262 → 0.9.265

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/locks.js CHANGED
@@ -25,6 +25,8 @@ var async = require("async");
25
25
  */
26
26
  exports = module.exports = function()
27
27
  {
28
+ var lockTimeoutMs = 120000; // two minutes
29
+
28
30
  var provider = null;
29
31
 
30
32
  var r = {};
@@ -72,12 +74,55 @@ exports = module.exports = function()
72
74
  */
73
75
  var lock = r.lock = function(key, fn)
74
76
  {
75
- provider.lock(key, function(err, releaseFn) {
77
+ var __log = function(key, text) {
78
+ // var skip = false;
79
+ // if (key === "channels") { skip = true; }
80
+ // if (!skip) {
81
+ // console.log("[LOCK: " + key + "] " + text);
82
+ // }
83
+ };
84
+
85
+ __log(key, "request");
86
+ provider.lock(key, function(err, _releaseFn) {
87
+
88
+ // wrap the releaseFn with a wrapper that can only fire once
89
+ var releaseFn = function(_releaseFn)
90
+ {
91
+ var triggered = false;
92
+ return function() {
93
+ if (!triggered) {
94
+ triggered = true;
95
+ _releaseFn();
96
+ return true;
97
+ }
98
+
99
+ return false;
100
+ }
101
+ }(_releaseFn);
102
+
103
+ // after 120 seconds, we force release lock (if it hasn't already been released)
104
+ (function(key, releaseFn) {
105
+ setTimeout(function() {
106
+ var released = releaseFn();
107
+ if (released) {
108
+ __log(key, "timed out, released");
109
+ }
110
+ }, lockTimeoutMs);
111
+ })(key, releaseFn);
112
+
113
+ __log(key, "taken");
114
+
76
115
  fn(err, function(afterReleaseCallback) {
116
+ __log(key, "pre-release");
77
117
 
78
- releaseFn();
79
-
80
- if (afterReleaseCallback)
118
+ var released = releaseFn();
119
+ if (released) {
120
+ __log(key, "released");
121
+ } else {
122
+ __log(key, "not released, was previously released on timeout");
123
+ }
124
+
125
+ if (released && afterReleaseCallback)
81
126
  {
82
127
  afterReleaseCallback();
83
128
  }
@@ -1,6 +1,4 @@
1
- var path = require("path");
2
-
3
- var ReadWriteLock = require("rwlock");
1
+ var AsyncLock = require('async-lock');
4
2
 
5
3
  /**
6
4
  * Simple in-memory lock service.
@@ -12,8 +10,8 @@ var ReadWriteLock = require("rwlock");
12
10
  exports = module.exports = function(lockConfig)
13
11
  {
14
12
  var r = {};
15
-
16
- var locker = new ReadWriteLock();
13
+
14
+ var lock = new AsyncLock();
17
15
 
18
16
  r.init = function(callback)
19
17
  {
@@ -22,8 +20,13 @@ exports = module.exports = function(lockConfig)
22
20
 
23
21
  r.lock = function(key, fn)
24
22
  {
25
- locker.writeLock(key, function(releaseCallbackFn) {
23
+ lock.acquire(key, function(releaseCallbackFn) {
26
24
  fn(null, releaseCallbackFn);
25
+ }, function(err, ret) {
26
+ // lock was released
27
+ if (err) {
28
+ console.error("Memory Lock heard error: ", err, " return value: ", ret);
29
+ }
27
30
  });
28
31
  };
29
32
 
@@ -13,7 +13,7 @@ exports = module.exports = function(locksConfig)
13
13
  var redlock = null;
14
14
  var client = null;
15
15
 
16
- var logger = redisHelper.redisLogger("REDIS_LOCKS", "CLOUDCMS_LOCKS_", "error")
16
+ var logger = redisHelper.redisLogger("REDIS_LOCKS", "CLOUDCMS_LOCKS_", "debug")
17
17
 
18
18
  var r = {};
19
19
 
@@ -9,15 +9,25 @@ class SessionAdapter extends AbstractAdapter
9
9
 
10
10
  identify(req, callback)
11
11
  {
12
- if (req.session && req.session._auth_profile)
12
+ if (req.session)
13
13
  {
14
- var properties = {
15
- "token": req.session._auth_profile.unique_name,
16
- "trusted": true,
17
- "profile": req.session._auth_profile
18
- };
19
-
20
- return callback(null, properties);
14
+ return req.session.reload(function() {
15
+
16
+ if (req.session._auth_profile)
17
+ {
18
+ var properties = {
19
+ "token": req.session._auth_profile.unique_name,
20
+ "trusted": true,
21
+ "profile": req.session._auth_profile
22
+ };
23
+
24
+ return callback(null, properties);
25
+ }
26
+ else
27
+ {
28
+ return super.identify(req, callback);
29
+ }
30
+ });
21
31
  }
22
32
 
23
33
  return super.identify(req, callback);
@@ -436,15 +436,21 @@ exports = module.exports = function()
436
436
  }
437
437
  else
438
438
  {
439
- req.session.registration_strategy_id = strategyId;
440
- req.session.registration_user_object = userObject;
441
- req.session.registration_user_identifier = userIdentifier;
442
- req.session.registration_groups_array = groupsArray;
443
- req.session.registration_mandatory_groups_array = mandatoryGroupsArray;
444
- req.session.registration_token = info.token;
445
- req.session.registration_refresh_token = info.refresh_token;
446
-
447
- return res.redirect(registrationRedirectUrl);
439
+ return req.session.reload(function() {
440
+
441
+ req.session.registration_strategy_id = strategyId;
442
+ req.session.registration_user_object = userObject;
443
+ req.session.registration_user_identifier = userIdentifier;
444
+ req.session.registration_groups_array = groupsArray;
445
+ req.session.registration_mandatory_groups_array = mandatoryGroupsArray;
446
+ req.session.registration_token = info.token;
447
+ req.session.registration_refresh_token = info.refresh_token;
448
+
449
+ req.session.save(function() {
450
+ res.redirect(registrationRedirectUrl);
451
+ });
452
+
453
+ });
448
454
  }
449
455
  });
450
456
  }
@@ -765,13 +771,19 @@ exports = module.exports = function()
765
771
  }
766
772
  else
767
773
  {
768
- req.session.registration_strategy_id = strategyId;
769
- req.session.registration_user_object = properties.user_object;
770
- req.session.registration_user_identifier = properties.user_identifier;
771
- req.session.registration_token = properties.token;
772
- req.session.registration_refresh_token = properties.refresh_token;
773
-
774
- return res.redirect(registrationRedirect);
774
+ return req.session.reload(function() {
775
+
776
+ req.session.registration_strategy_id = strategyId;
777
+ req.session.registration_user_object = properties.user_object;
778
+ req.session.registration_user_identifier = properties.user_identifier;
779
+ req.session.registration_token = properties.token;
780
+ req.session.registration_refresh_token = properties.refresh_token;
781
+
782
+ req.session.save(function() {
783
+ res.redirect(registrationRedirect);
784
+ });
785
+
786
+ });
775
787
  }
776
788
  }
777
789
 
@@ -15,8 +15,11 @@ class DefaultAuthenticator extends AbstractAuthenticator
15
15
  {
16
16
  return req.logIn(gitanaUser, function() {
17
17
 
18
- if (req.session && req.session.save) {
19
- req.session.save();
18
+ if (req.session)
19
+ {
20
+ return req.session.save(function() {
21
+ callback();
22
+ });
20
23
  }
21
24
 
22
25
  callback();
@@ -25,8 +25,11 @@ class SessionAuthenticator extends DefaultAuthenticator
25
25
 
26
26
  req.user = gitanaUser;
27
27
 
28
- if (req.session && req.session.save) {
29
- req.session.save();
28
+ if (req.session)
29
+ {
30
+ return req.session.save(function() {
31
+ callback();
32
+ });
30
33
  }
31
34
 
32
35
  callback();
@@ -41,17 +41,20 @@ exports = module.exports = function()
41
41
  }
42
42
  */
43
43
 
44
- if (pathRequiresAuthorization) {
45
- if (req.session && req.session.requestContext) {
46
- next();
47
- }
48
- else {
49
- res.redirect("/login");
50
- }
44
+ if (!pathRequiresAuthorization)
45
+ {
46
+ return next();
51
47
  }
52
- else {
48
+
49
+ if (req.session && req.session.requestContext)
50
+ {
53
51
  next();
54
52
  }
53
+ else
54
+ {
55
+ res.redirect("/login");
56
+ }
57
+
55
58
  });
56
59
  };
57
60
 
@@ -52,9 +52,14 @@ class AbstractAsyncProvider extends AbstractProvider
52
52
  {
53
53
  var self = this;
54
54
 
55
+ //console.log("a1");
55
56
  self._lock("channels", function(err, releaseLockFn) {
57
+ // console.log("a2: ", err);
58
+ // console.log("a3: ", releaseLockFn);
56
59
  self.doRegister(channelId, user, function(err) {
60
+ // console.log("a4 ", err);
57
61
  callback(err);
62
+ // console.log("a5: ", releaseLockFn);
58
63
  return releaseLockFn();
59
64
  });
60
65
  });
@@ -206,38 +211,40 @@ class AbstractAsyncProvider extends AbstractProvider
206
211
  return done();
207
212
  }
208
213
 
209
- if (channel.users && Object.keys(channel.users).length > 0)
214
+ if (!channel.users || Object.keys(channel.users).length === 0)
210
215
  {
211
- // populate all of the user IDs that need to be removed
212
- var userIdsToRemove = [];
213
- for (var userId in channel.users)
216
+ return done();
217
+ }
218
+
219
+ // populate all of the user IDs that need to be removed
220
+ var userIdsToRemove = [];
221
+ for (var userId in channel.users)
222
+ {
223
+ var entry = channel.users[userId];
224
+ if (entry.time < beforeMs)
214
225
  {
215
- var entry = channel.users[userId];
216
- if (entry.time < beforeMs)
217
- {
218
- updatedMembershipChannelIds.push(channelId);
219
- userIdsToRemove.push(userId);
220
-
221
- var expiredUserIds = expiredUserIdsByChannelId[channelId]
222
- if (!expiredUserIds) {
223
- expiredUserIds = expiredUserIdsByChannelId[channelId] = [];
224
- }
225
-
226
- expiredUserIds.push(userId);
226
+ updatedMembershipChannelIds.push(channelId);
227
+ userIdsToRemove.push(userId);
228
+
229
+ var expiredUserIds = expiredUserIdsByChannelId[channelId]
230
+ if (!expiredUserIds) {
231
+ expiredUserIds = expiredUserIdsByChannelId[channelId] = [];
227
232
  }
233
+
234
+ expiredUserIds.push(userId);
228
235
  }
229
-
230
- // remove the user IDs
231
- for (var i = 0; i < userIdsToRemove.length; i++)
232
- {
233
- delete channel.users[userIdsToRemove[i]];
234
- }
235
-
236
- self.writeChannel(channelId, channel, function() {
237
- done();
238
- });
239
236
  }
240
237
 
238
+ // remove the user IDs
239
+ for (var i = 0; i < userIdsToRemove.length; i++)
240
+ {
241
+ delete channel.users[userIdsToRemove[i]];
242
+ }
243
+
244
+ self.writeChannel(channelId, channel, function() {
245
+ done();
246
+ });
247
+
241
248
  });
242
249
  };
243
250
  }(channelId, updatedMembershipChannelIds, expiredUserIdsByChannelId, beforeMs);
@@ -441,7 +441,13 @@ exports = module.exports = function()
441
441
  if (err) {
442
442
  return callback(err);
443
443
  }
444
-
444
+
445
+ var branch = CACHED_BRANCHES[cacheKey];
446
+ if (branch) {
447
+ callback(null, Chain(branch));
448
+ return releaseLockFn();
449
+ }
450
+
445
451
  var loadFn = function(finished) {
446
452
 
447
453
  Chain(repository).trap(function(e) {
@@ -468,23 +474,21 @@ exports = module.exports = function()
468
474
 
469
475
  if (err) {
470
476
 
477
+ callback(err);
478
+
471
479
  // release the lock
472
- releaseLockFn();
473
-
474
- // do the callback
475
- return callback(err);
480
+ return releaseLockFn();
476
481
  }
477
482
 
478
483
  // success!
479
484
 
480
485
  // store in cache
481
486
  CACHED_BRANCHES[cacheKey] = branch;
482
-
487
+
488
+ callback(null, branch);
489
+
483
490
  // release the lock
484
- releaseLockFn();
485
-
486
- // do the callback
487
- return callback(null, branch);
491
+ return releaseLockFn();
488
492
  });
489
493
  }
490
494
 
@@ -1443,11 +1447,10 @@ exports = module.exports = function()
1443
1447
 
1444
1448
  // the range requested (for streaming)
1445
1449
  //var range = req.headers["range"];
1446
-
1450
+
1447
1451
  cloudcmsUtil.preview(contentStore, gitana, repositoryId, branchId, nodeId, nodePath, attachmentId, locale, previewId, size, mimetype, forceReload, function(err, filePath, cacheInfo, releaseLock) {
1448
1452
 
1449
- if (err)
1450
- {
1453
+ if (err) {
1451
1454
  req.log("Error on preview node: " + err.message + ", err: " + JSON.stringify(err));
1452
1455
  }
1453
1456
 
@@ -1479,8 +1482,7 @@ exports = module.exports = function()
1479
1482
  // UZI: file deleted by invalidate before this gets called
1480
1483
  contentStore.sendFile(res, filePath, cacheInfo, function(err) {
1481
1484
 
1482
- if (err)
1483
- {
1485
+ if (err) {
1484
1486
  util.handleSendFileError(req, res, filePath, cacheInfo, req.log, err);
1485
1487
  }
1486
1488
 
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  },
7
7
  "name": "cloudcms-server",
8
8
  "description": "Cloud CMS Application Server Module",
9
- "version": "0.9.262",
9
+ "version": "0.9.265",
10
10
  "repository": {
11
11
  "type": "git",
12
12
  "url": "git://github.com/gitana/cloudcms-server.git"
@@ -20,6 +20,7 @@
20
20
  "alpaca": "^1.5.27",
21
21
  "archiver": "^1.3.0",
22
22
  "async": "^3.2.3",
23
+ "async-lock": "^1.3.2",
23
24
  "aws-sdk": "^2.544.0",
24
25
  "basic-auth": "^1.1.0",
25
26
  "body-parser": "^1.19.0",
@@ -79,7 +80,6 @@
79
80
  "request": "^2.88.0",
80
81
  "request-param": "^1.0.1",
81
82
  "response-time": "^2.3.2",
82
- "rwlock": "^5.0.0",
83
83
  "semver": "^5.7.1",
84
84
  "serve-favicon": "^2.5.0",
85
85
  "session-file-store": "^0.2.2",