alchemymvc 1.3.1 → 1.3.2

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.
@@ -7,7 +7,7 @@ let queue_check_id,
7
7
  *
8
8
  * @author Jelle De Loecker <jelle@elevenways.be>
9
9
  * @since 1.3.1
10
- * @version 1.3.1
10
+ * @version 1.3.2
11
11
  *
12
12
  * @param {Conduit} conduit The original conduit
13
13
  */
@@ -43,6 +43,9 @@ const Postponement = Function.inherits('Alchemy.Base', 'Alchemy.Conduit', functi
43
43
  // When did this postponement end?
44
44
  this.ended = null;
45
45
 
46
+ // Has this postponement expired?
47
+ this.expired = false;
48
+
46
49
  // Has this postponement been released yet?
47
50
  this.released = false;
48
51
 
@@ -127,13 +130,15 @@ Postponement.setProperty(function time_unchecked() {
127
130
  *
128
131
  * @author Jelle De Loecker <jelle@elevenways.be>
129
132
  * @since 1.3.1
130
- * @version 1.3.1
133
+ * @version 1.3.2
131
134
  *
132
135
  * @return {Number}
133
136
  */
134
137
  Postponement.setProperty(function has_been_abandoned() {
135
138
 
136
- if (this.time_unchecked > 30 * 1000) {
139
+ // Postponements that haven't been checked in 3 minutes
140
+ // are considered abandoned
141
+ if (this.time_unchecked > 180_000) {
137
142
  return true;
138
143
  }
139
144
 
@@ -236,7 +241,7 @@ Postponement.setStatic(function checkQueue() {
236
241
  *
237
242
  * @author Jelle De Loecker <jelle@elevenways.be>
238
243
  * @since 1.3.1
239
- * @version 1.3.1
244
+ * @version 1.3.2
240
245
  *
241
246
  * @param {Conduit} conduit The new conduit
242
247
  */
@@ -253,7 +258,19 @@ Postponement.setMethod(function handleRequest(conduit) {
253
258
  location : null,
254
259
  };
255
260
 
256
- if (this.attemptUnlock()) {
261
+ if (this.released) {
262
+ data.allowed = true;
263
+ data.location = this.url;
264
+ } else if (this.expired) {
265
+ // If the request has expired, send them to the original url again
266
+ data.allowed = true;
267
+ data.location = this.original_path;
268
+ } else if (this.attemptUnlock()) {
269
+ data.allowed = true;
270
+ data.location = this.url;
271
+ } else if (data.position == null) {
272
+ // Something else has gone wrong?
273
+ // Send them to the url anyway
257
274
  data.allowed = true;
258
275
  data.location = this.url;
259
276
  }
@@ -276,7 +293,7 @@ Postponement.setMethod(function handleRequest(conduit) {
276
293
  *
277
294
  * @author Jelle De Loecker <jelle@elevenways.be>
278
295
  * @since 1.3.1
279
- * @version 1.3.1
296
+ * @version 1.3.2
280
297
  *
281
298
  * @return {Boolean} True if the request is being resumed
282
299
  */
@@ -286,6 +303,8 @@ Postponement.setMethod(function attemptUnlock() {
286
303
  return true;
287
304
  }
288
305
 
306
+ this.last_check = Date.now();
307
+
289
308
  Postponement.scheduleQueueCheck();
290
309
 
291
310
  if (this.position_in_queue > 5) {
@@ -431,6 +450,7 @@ Postponement.setMethod(function remove(expired) {
431
450
  */
432
451
  Postponement.setMethod(function expire() {
433
452
  this.remove(true);
453
+ this.expired = true;
434
454
  });
435
455
 
436
456
  /**
@@ -294,7 +294,7 @@ ClientBase.setMethod(function getModel(name, init, options) {
294
294
  *
295
295
  * @author Jelle De Loecker <jelle@elevenways.be>
296
296
  * @since 1.1.1
297
- * @version 1.3.0
297
+ * @version 1.3.2
298
298
  *
299
299
  * @param {String} name The name of the event to emit
300
300
  * @param {Array} args The parameters to pass to the event
@@ -330,7 +330,12 @@ ClientBase.setMethod(function issueEvent(name, args, next) {
330
330
 
331
331
  if (err) {
332
332
  pledge.reject(err);
333
- return next(err);
333
+
334
+ if (next) {
335
+ next(err);
336
+ }
337
+
338
+ return;
334
339
  }
335
340
 
336
341
  if (result !== false) {
@@ -90,6 +90,9 @@ global.Alchemy = Function.inherits('Informer', 'Alchemy', function Alchemy() {
90
90
  // All caches
91
91
  this.caches = {};
92
92
 
93
+ // Extra toobusy checks
94
+ this.extra_toobusy_checks = [];
95
+
93
96
  // Also store the version in the process versions object
94
97
  process.versions.alchemy = this.version;
95
98
 
@@ -249,24 +252,55 @@ Alchemy.setMethod(function systemLoad() {
249
252
  return percentage;
250
253
  });
251
254
 
255
+ /**
256
+ * Register an extra toobusy check method.
257
+ * These will be checked after event loop lag & system load are deemed OK.
258
+ *
259
+ * @author Jelle De Loecker <jelle@elevenways.be>
260
+ * @since 1.3.2
261
+ * @version 1.3.2
262
+ */
263
+ Alchemy.setMethod(function addToobusyCheck(fnc) {
264
+ this.extra_toobusy_checks.push(fnc);
265
+ });
266
+
252
267
  /**
253
268
  * Is the server currently too busy, overloaded in some way?
254
269
  *
255
270
  * @author Jelle De Loecker <jelle@elevenways.be>
256
271
  * @since 1.3.1
257
- * @version 1.3.1
272
+ * @version 1.3.2
258
273
  *
259
274
  * @return {Boolean}
260
275
  */
261
276
  Alchemy.setMethod(function isTooBusy() {
262
277
 
263
- // First check if it's too busy because of lag
278
+ // First check if it's too busy because of event loop lag
264
279
  if (this.toobusy()) {
265
280
  return true;
266
281
  }
267
282
 
268
- // Then check the load average
269
- return this.systemLoad() > 90;
283
+ if (this.settings.max_system_load > 0) {
284
+ // Then check the load average
285
+ if (this.systemLoad() > this.settings.max_system_load) {
286
+ return true;
287
+ }
288
+ }
289
+
290
+ if (this.extra_toobusy_checks.length > 0) {
291
+
292
+ for (let fnc of this.extra_toobusy_checks) {
293
+ try {
294
+ if (fnc()) {
295
+ return true;
296
+ }
297
+ } catch (err) {
298
+ alchemy.distinctProblem('error-extra-toobusy-check', 'Extra toobusy check failed', {error: err});
299
+ }
300
+ }
301
+ }
302
+
303
+ return false;
270
304
  });
271
305
 
272
306
  /**
@@ -294,7 +328,7 @@ Alchemy.setMethod(function isTooBusyForRequests() {
294
328
  *
295
329
  * @author Jelle De Loecker <jelle@elevenways.be>
296
330
  * @since 1.3.1
297
- * @version 1.3.1
331
+ * @version 1.3.2
298
332
  *
299
333
  * @return {Boolean}
300
334
  */
@@ -306,8 +340,12 @@ Alchemy.setMethod(function isTooBusyForAjax() {
306
340
 
307
341
  let lag = this.lagInMs();
308
342
 
309
- if (lag > (alchemy.settings.toobusy * 3)) {
310
- return true;
343
+ let max_event_loop_lag = alchemy.settings.max_event_loop_lag || alchemy.settings.toobusy;
344
+
345
+ if (max_event_loop_lag) {
346
+ if (lag > (max_event_loop_lag * 3)) {
347
+ return true;
348
+ }
311
349
  }
312
350
 
313
351
  return false;
@@ -57,9 +57,11 @@ alchemy.hawkejs = Classes.Hawkejs.Hawkejs.getInstance();
57
57
  */
58
58
  alchemy.toobusy = alchemy.use('toobusy-js', 'toobusy');
59
59
 
60
+ let max_event_loop_lag = alchemy.settings.max_event_loop_lag || alchemy.settings.toobusy;
61
+
60
62
  // If the config is a number, use that as the lag threshold
61
- if (typeof alchemy.settings.toobusy === 'number') {
62
- alchemy.toobusy.maxLag(alchemy.settings.toobusy);
63
+ if (typeof max_event_loop_lag === 'number') {
64
+ alchemy.toobusy.maxLag(max_event_loop_lag);
63
65
  }
64
66
 
65
67
  /**
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "alchemymvc",
3
3
  "description": "MVC framework for Node.js",
4
- "version": "1.3.1",
4
+ "version": "1.3.2",
5
5
  "author": "Jelle De Loecker <jelle@elevenways.be>",
6
6
  "keywords": [
7
7
  "alchemy",
@@ -22,7 +22,7 @@
22
22
  "chokidar" : "~3.5.3",
23
23
  "formidable" : "~2.0.1",
24
24
  "graceful-fs" : "~4.2.9",
25
- "hawkejs" : "~2.3.1",
25
+ "hawkejs" : "~2.3.2",
26
26
  "jsondiffpatch" : "~0.4.1",
27
27
  "mime" : "~3.0.0",
28
28
  "minimist" : "~1.2.5",
@@ -31,7 +31,7 @@
31
31
  "mongodb" : "~3.6.6",
32
32
  "ncp" : "~2.0.0",
33
33
  "postcss" : "~8.4.6",
34
- "protoblast" : "~0.8.0",
34
+ "protoblast" : "~0.8.2",
35
35
  "semver" : "~7.3.5",
36
36
  "socket.io" : "~2.4.0",
37
37
  "@11ways/socket.io-stream" : "~0.9.2",