cloudcms-server 0.9.260 → 0.9.263

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.
@@ -163,10 +163,10 @@ var handleInvalidate = function(req, res)
163
163
  // new timestamp
164
164
  process.env.CLOUDCMS_APPSERVER_TIMESTAMP = new Date().getTime();
165
165
 
166
- // update all socket clients
167
- process.IO.sockets.emit("timestamp", {
168
- "timestamp": process.env.CLOUDCMS_APPSERVER_TIMESTAMP
169
- });
166
+ // // update all socket clients
167
+ // process.IO.sockets.emit("timestamp", {
168
+ // "timestamp": process.env.CLOUDCMS_APPSERVER_TIMESTAMP
169
+ // });
170
170
 
171
171
  console.log("Server timestamp regenerated");
172
172
 
@@ -1,5 +1,18 @@
1
1
  const cluster = require("cluster");
2
2
 
3
+ // Handle uncaught exceptions...
4
+ process.on('uncaughtException', function(err, source) {
5
+ // if (err === "read ECONNRESET")
6
+ // {
7
+ // // skip
8
+ // }
9
+ // else
10
+ // {
11
+ console.log(`Launchpad - process received event 'uncaughtException': ${err}, source: ${source}`);
12
+ console.log(err.stack);
13
+ // }
14
+ });
15
+
3
16
  module.exports = function(type, config, options)
4
17
  {
5
18
  if (!type) {
@@ -6,6 +6,9 @@ const numCPUs = require("os").cpus().length;
6
6
  const { setupMaster, setupWorker } = require("@socket.io/sticky");
7
7
  const { createAdapter, setupPrimary } = require("@socket.io/cluster-adapter");
8
8
 
9
+ // numCPUs = 1;
10
+ // console.log("FORCE ONE CPU");
11
+
9
12
  module.exports = function(config) {
10
13
 
11
14
  var r = {};
@@ -14,7 +17,7 @@ module.exports = function(config) {
14
17
  {
15
18
  // setup sticky sessions
16
19
  setupMaster(httpServer, {
17
- loadBalancingMethod: "least-connection",
20
+ loadBalancingMethod: "least-connection"
18
21
  });
19
22
 
20
23
  // setup connections between the workers
@@ -46,14 +49,23 @@ module.exports = function(config) {
46
49
  var worker = cluster.fork(workerEnv);
47
50
 
48
51
  worker.on('message', function (msg, c) {
52
+ //console.log("Worker message: " + msg + ", c: " + c);
49
53
  if (msg === "worker-startup") {
50
54
  startupCount++;
51
55
  }
52
56
  });
53
57
 
58
+ worker.on('error', function(err) {
59
+ console.log("Worker.on(error) - " + JSON.stringify(err));
60
+ });
61
+
54
62
  workers.push(worker);
55
63
  }
56
64
 
65
+ cluster.on("error", function(err) {
66
+ console.log("Cluster.on(error) - " + JSON.stringify(err));
67
+ });
68
+
57
69
  cluster.on("exit", (worker) => {
58
70
  console.log(`Worker ${worker.process.pid} died`);
59
71
  cluster.fork();
@@ -79,19 +91,25 @@ module.exports = function(config) {
79
91
  // worker
80
92
 
81
93
  const io = new Server(httpServer);
82
-
94
+ httpServer.io = io;
95
+
83
96
  // use the cluster adapter
84
97
  io.adapter(createAdapter());
85
98
 
86
99
  // setup connection with the primary process
87
100
  setupWorker(io);
88
-
101
+
102
+ // on connect
89
103
  io.on("connection", (socket) => {
90
104
  // TODO
105
+
106
+ // always catch err
107
+ socket.on("error", function(err) {
108
+ console.log("Caught socket error");
109
+ console.log(err.stack);
110
+ });
91
111
  });
92
112
 
93
- httpServer.io = io;
94
-
95
113
  return callback();
96
114
  };
97
115
 
@@ -1,6 +1,6 @@
1
1
  const { Server } = require("socket.io");
2
2
  const { setupWorker } = require("@socket.io/sticky");
3
- const { createAdapter } = require("@socket.io/cluster-adapter");
3
+ const { createAdapter } = require("@socket.io/redis-adapter");
4
4
  const redisHelper = require("../../util/redis");
5
5
 
6
6
  const clusterLauncherFactory = require("./cluster");
@@ -23,30 +23,61 @@ module.exports = function(config) {
23
23
 
24
24
  r.afterStartServer = function(app, httpServer, callback)
25
25
  {
26
- const io = new Server(httpServer);
27
-
28
- (async function() {
26
+ (async function(app, httpServer, callback) {
29
27
  var redisOptions = redisHelper.redisOptions({}, "CLOUDCMS_CLUSTER");
30
28
  await redisHelper.createAndConnect(redisOptions, function(err, _client) {
31
-
29
+
32
30
  const pubClient = _client;
33
31
  const subClient = pubClient.duplicate();
34
-
35
- io.adapter(createAdapter(pubClient, subClient));
36
- //io.listen(httpServerPort);
37
-
38
- io.on("connection", (socket) => {
39
- // TODO
32
+
33
+ pubClient.on("error", function(err) {
34
+ // something went wrong
35
+ console.log("Pub Client caught error: ", err);
40
36
  });
41
-
37
+
38
+ subClient.on("error", function(err) {
39
+ // something went wrong
40
+ console.log("Sub Client caught error: ", err);
41
+ });
42
+
43
+ const io = new Server(httpServer);
44
+ httpServer.io = io;
45
+
46
+ io.engine.on("connection_error", function(err) {
47
+ // console.log("CONNECTION ERROR");
48
+ // console.log("REQUEST: " + err.req); // the request object
49
+ // console.log("CODE: " + err.code); // the error code, for example 1
50
+ // console.log("MESSAGE: " + err.message); // the error message, for example "Session ID unknown"
51
+ // console.log("CONTEXT: " + err.context); // some additional error context
52
+ });
53
+
54
+ // use the redis adapter
55
+ io.adapter(createAdapter(pubClient, subClient, {
56
+ //publishOnSpecificResponseChannel: true
57
+ }));
58
+
42
59
  // setup connection with the primary process
43
60
  setupWorker(io);
44
-
45
- httpServer.io = io;
46
-
61
+
62
+ // on connect
63
+ io.on("connection", (socket) => {
64
+ //console.log("Redis Launcher on('connection') - socket id:" + socket.id);
65
+ // socket.on('message', function(m) {
66
+ // console.log("Socket Connection message: " + m);
67
+ // });
68
+ //
69
+ // // always catch err
70
+ // socket.on("error", function(err) {
71
+ // console.log("Caught socket error");
72
+ // console.log(err.stack);
73
+ // });
74
+
75
+ // TODO
76
+ });
77
+
47
78
  return callback();
48
79
  });
49
- })();
80
+ })(app, httpServer, callback);
50
81
  };
51
82
 
52
83
  return r;
@@ -20,6 +20,12 @@ module.exports = function(config) {
20
20
 
21
21
  io.on("connection", (socket) => {
22
22
  // TODO
23
+
24
+ // always catch err
25
+ socket.on("error", function(err) {
26
+ console.log("Caught socket error");
27
+ console.log(err.stack);
28
+ });
23
29
  });
24
30
 
25
31
  httpServer.io = io;
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
 
@@ -1,6 +1,5 @@
1
1
  //var auth = require("../../../util/auth");
2
2
 
3
- //var SamlStrategy = require("../../../temp/passport-saml").Strategy;
4
3
  var SamlStrategy = require('passport-saml').Strategy;
5
4
  var AbstractProvider = require("./abstract");
6
5
 
@@ -60,10 +60,15 @@ exports = module.exports = function()
60
60
  if (!process.configuration.awareness.config) {
61
61
  process.configuration.awareness.config = {};
62
62
  }
63
-
63
+
64
+ // init any plugins?
65
+ if (!process.configuration.awareness.plugins) {
66
+ process.configuration.awareness.plugins = [];
67
+ }
68
+
64
69
  var type = process.configuration.awareness.type;
65
70
  var config = process.configuration.awareness.config;
66
-
71
+
67
72
  var providerFactory = require("./providers/" + type);
68
73
  provider = new providerFactory(config);
69
74
 
@@ -74,12 +79,6 @@ exports = module.exports = function()
74
79
  return callback(err);
75
80
  }
76
81
 
77
- // init any plugins?
78
- if (!process.configuration.awareness.plugins) {
79
- process.configuration.awareness.plugins = [];
80
- }
81
-
82
-
83
82
  var fns = [];
84
83
  for (var i = 0; i < pluginPaths.length; i++)
85
84
  {
@@ -115,15 +114,18 @@ exports = module.exports = function()
115
114
  /**
116
115
  * This gets called whenever a new socket is connected to the Cloud CMS server.
117
116
  *
117
+ * @param io
118
+ * @param callback
119
+ *
118
120
  * @type {Function}
119
121
  */
120
- var initSocketIO = r.initSocketIO = function(callback) {
121
-
122
+ var initSocketIO = r.initSocketIO = function(io, callback) {
123
+
122
124
  // initialize socket IO event handlers so that awareness binds to any new, incoming sockets
123
- socketInit(process.IO);
125
+ socketInit(io);
124
126
 
125
127
  // ensure the reaper is initialized
126
- reaperInit(process.IO, REAP_FREQUENCY_MS, REAP_MAX_AGE_MS, function(err) {
128
+ reaperInit(io, REAP_FREQUENCY_MS, REAP_MAX_AGE_MS, function(err) {
127
129
  callback(err);
128
130
  });
129
131
  };
@@ -172,7 +174,7 @@ exports = module.exports = function()
172
174
  // when a socket.io connection is established, we set up some default listeners for events that the client
173
175
  // may emit to us
174
176
  io.on("connection", function(socket) {
175
-
177
+
176
178
  // "register" -> indicates that a user is in a channel
177
179
  socket.on("register", function(channelId, user, dirty, callback) {
178
180
 
@@ -193,24 +195,32 @@ exports = module.exports = function()
193
195
  return callback(err);
194
196
  }
195
197
 
196
- // if we were already registered, just callback
197
- // however, if "dirty" is set, then we always hand back membership
198
- if (!dirty && alreadyRegistered)
199
- {
200
- return callback();
201
- }
202
-
203
- if (!alreadyRegistered)
204
- {
205
- // logger.info("New registration - channelId: " + channelId + ",userId=" + user.id + " (" + user.name + ")");
206
-
198
+ // // if we were already registered, just callback
199
+ // // however, if "dirty" is set, then we always hand back membership
200
+ // if (!dirty && alreadyRegistered)
201
+ // {
202
+ // logger.info("Already registered, not dirty - channelId: " + channelId + ",userId=" + user.id + " (" + user.name + ")");
203
+ //
204
+ // return callback();
205
+ // }
206
+ //
207
+ // if (!alreadyRegistered)
208
+ // {
209
+ // logger.info("New registration - channelId: " + channelId + ",userId=" + user.id + " (" + user.name + ")");
210
+
211
+ //logger.info("Register - channelId: " + channelId + ", userId=" + user.id + " (" + user.name + ")");
207
212
  socket.join(channelId);
208
- }
213
+ //}
209
214
 
210
215
  discover(channelId, function(err, userArray) {
211
216
 
212
- if (!err) {
213
- logger.info("Discover - channelId: " + channelId + ", userId=" + user.id + " (" + user.name + ") handing back: " + userArray.length);
217
+ if (err)
218
+ {
219
+ logger.info("Discover - channelId: " + channelId + ", err: " + JSON.stringify(err));
220
+ }
221
+ else
222
+ {
223
+ //logger.info("Discover - channelId: " + channelId + ", userId=" + user.id + " (" + user.name + ") handing back: " + userArray.length);
214
224
  io.sockets.in(channelId).emit("membershipChanged", channelId, userArray);
215
225
  }
216
226
 
@@ -412,6 +422,8 @@ exports = module.exports = function()
412
422
  */
413
423
  var register = r.register = function(channelId, user, callback)
414
424
  {
425
+ //console.log("Awareness - heard register, channel: " + channelId + ", user: " + user.id);
426
+
415
427
  provider.register(channelId, user, callback);
416
428
  };
417
429