wingbot-mongodb 3.1.2 → 3.2.1

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.
@@ -1 +1 @@
1
- {"parent":null,"pid":67090,"argv":["/usr/local/bin/node","/Users/david/Development/wingbot-mongodb/node_modules/.bin/mocha","./test"],"execArgv":[],"cwd":"/Users/david/Development/wingbot-mongodb","time":1672231628548,"ppid":67089,"coverageFilename":"/Users/david/Development/wingbot-mongodb/.nyc_output/348f41df-6e7a-4377-9c78-40269fd1eaef.json","externalId":"","uuid":"348f41df-6e7a-4377-9c78-40269fd1eaef","files":["/Users/david/Development/wingbot-mongodb/src/BaseStorage.js","/Users/david/Development/wingbot-mongodb/src/defaultLogger.js","/Users/david/Development/wingbot-mongodb/src/AttachmentCache.js","/Users/david/Development/wingbot-mongodb/src/AuditLogStorage.js","/Users/david/Development/wingbot-mongodb/src/BotConfigStorage.js","/Users/david/Development/wingbot-mongodb/src/BotTokenStorage.js","/Users/david/Development/wingbot-mongodb/src/tokenFactory.js","/Users/david/Development/wingbot-mongodb/src/ChatLogStorage.js","/Users/david/Development/wingbot-mongodb/src/NotificationsStorage.js","/Users/david/Development/wingbot-mongodb/src/StateStorage.js"]}
1
+ {"parent":null,"pid":69488,"argv":["/usr/local/bin/node","/Users/david/Development/wingbot-mongodb/node_modules/.bin/mocha","./test"],"execArgv":[],"cwd":"/Users/david/Development/wingbot-mongodb","time":1676391651316,"ppid":69487,"coverageFilename":"/Users/david/Development/wingbot-mongodb/.nyc_output/6a7ed916-683a-43fd-8624-795a77e80a4a.json","externalId":"","uuid":"6a7ed916-683a-43fd-8624-795a77e80a4a","files":["/Users/david/Development/wingbot-mongodb/src/BaseStorage.js","/Users/david/Development/wingbot-mongodb/src/defaultLogger.js","/Users/david/Development/wingbot-mongodb/src/AttachmentCache.js","/Users/david/Development/wingbot-mongodb/src/AuditLogStorage.js","/Users/david/Development/wingbot-mongodb/src/BotConfigStorage.js","/Users/david/Development/wingbot-mongodb/src/BotTokenStorage.js","/Users/david/Development/wingbot-mongodb/src/tokenFactory.js","/Users/david/Development/wingbot-mongodb/src/ChatLogStorage.js","/Users/david/Development/wingbot-mongodb/src/NotificationsStorage.js","/Users/david/Development/wingbot-mongodb/src/StateStorage.js"]}
@@ -1 +1 @@
1
- {"processes":{"348f41df-6e7a-4377-9c78-40269fd1eaef":{"parent":null,"children":[]}},"files":{"/Users/david/Development/wingbot-mongodb/src/BaseStorage.js":["348f41df-6e7a-4377-9c78-40269fd1eaef"],"/Users/david/Development/wingbot-mongodb/src/defaultLogger.js":["348f41df-6e7a-4377-9c78-40269fd1eaef"],"/Users/david/Development/wingbot-mongodb/src/AttachmentCache.js":["348f41df-6e7a-4377-9c78-40269fd1eaef"],"/Users/david/Development/wingbot-mongodb/src/AuditLogStorage.js":["348f41df-6e7a-4377-9c78-40269fd1eaef"],"/Users/david/Development/wingbot-mongodb/src/BotConfigStorage.js":["348f41df-6e7a-4377-9c78-40269fd1eaef"],"/Users/david/Development/wingbot-mongodb/src/BotTokenStorage.js":["348f41df-6e7a-4377-9c78-40269fd1eaef"],"/Users/david/Development/wingbot-mongodb/src/tokenFactory.js":["348f41df-6e7a-4377-9c78-40269fd1eaef"],"/Users/david/Development/wingbot-mongodb/src/ChatLogStorage.js":["348f41df-6e7a-4377-9c78-40269fd1eaef"],"/Users/david/Development/wingbot-mongodb/src/NotificationsStorage.js":["348f41df-6e7a-4377-9c78-40269fd1eaef"],"/Users/david/Development/wingbot-mongodb/src/StateStorage.js":["348f41df-6e7a-4377-9c78-40269fd1eaef"]},"externalIds":{}}
1
+ {"processes":{"6a7ed916-683a-43fd-8624-795a77e80a4a":{"parent":null,"children":[]}},"files":{"/Users/david/Development/wingbot-mongodb/src/BaseStorage.js":["6a7ed916-683a-43fd-8624-795a77e80a4a"],"/Users/david/Development/wingbot-mongodb/src/defaultLogger.js":["6a7ed916-683a-43fd-8624-795a77e80a4a"],"/Users/david/Development/wingbot-mongodb/src/AttachmentCache.js":["6a7ed916-683a-43fd-8624-795a77e80a4a"],"/Users/david/Development/wingbot-mongodb/src/AuditLogStorage.js":["6a7ed916-683a-43fd-8624-795a77e80a4a"],"/Users/david/Development/wingbot-mongodb/src/BotConfigStorage.js":["6a7ed916-683a-43fd-8624-795a77e80a4a"],"/Users/david/Development/wingbot-mongodb/src/BotTokenStorage.js":["6a7ed916-683a-43fd-8624-795a77e80a4a"],"/Users/david/Development/wingbot-mongodb/src/tokenFactory.js":["6a7ed916-683a-43fd-8624-795a77e80a4a"],"/Users/david/Development/wingbot-mongodb/src/ChatLogStorage.js":["6a7ed916-683a-43fd-8624-795a77e80a4a"],"/Users/david/Development/wingbot-mongodb/src/NotificationsStorage.js":["6a7ed916-683a-43fd-8624-795a77e80a4a"],"/Users/david/Development/wingbot-mongodb/src/StateStorage.js":["6a7ed916-683a-43fd-8624-795a77e80a4a"]},"externalIds":{}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wingbot-mongodb",
3
- "version": "3.1.2",
3
+ "version": "3.2.1",
4
4
  "description": "MongoDB storage for wingbot.ai",
5
5
  "main": "src/main.js",
6
6
  "scripts": {
@@ -33,12 +33,31 @@ function getNestedObjects (obj, nested, attr = null, ret = {}) {
33
33
 
34
34
  class BaseStorage {
35
35
 
36
+ static netFailuresIntervalMs = 600000; // 10 minutes
37
+
38
+ static netFailuresCount = 0;
39
+
40
+ static _killing = null;
41
+
42
+ static _failStack = [];
43
+
44
+ static killer = () => setTimeout(() => {
45
+ process.exit(1);
46
+ }, 10000);
47
+
48
+ static networkFailureErrorNames = [
49
+ 'MongoServerSelectionError',
50
+ 'MongoNetworkError',
51
+ 'MongoNetworkTimeoutError',
52
+ 'MongoTopologyClosedError'
53
+ ];
54
+
36
55
  /**
37
56
  *
38
57
  * @param {Db|{():Promise<Db>}} mongoDb
39
58
  * @param {string} collectionName
40
59
  * @param {{error:Function,log:Function}} [log] - console like logger
41
- * @param {boolean} [isCosmo]
60
+ * @param {boolean|number} [isCosmo]
42
61
  * @example
43
62
  *
44
63
  * const { BaseStorage } = require('winbot-mongodb');
@@ -67,7 +86,7 @@ class BaseStorage {
67
86
  constructor (mongoDb, collectionName, log = defaultLogger, isCosmo = false) {
68
87
  this._mongoDb = mongoDb;
69
88
  this._collectionName = collectionName;
70
- this._isCosmo = isCosmo;
89
+ this._isCosmo = typeof isCosmo === 'number' || isCosmo;
71
90
  this._log = log;
72
91
 
73
92
  /**
@@ -84,7 +103,11 @@ class BaseStorage {
84
103
 
85
104
  this._fixtures = [];
86
105
 
87
- if (isCosmo && !process.argv.some((a) => a.endsWith('mocha'))) {
106
+ if (typeof isCosmo === 'number') {
107
+ BaseStorage.netFailuresCount = isCosmo;
108
+ }
109
+
110
+ if (this._isCosmo && !process.argv.some((a) => a.endsWith('mocha'))) {
88
111
  process.nextTick(() => {
89
112
  const hasUniqueIndex = this._indexes.some((i) => i.options.unique);
90
113
 
@@ -96,6 +119,45 @@ class BaseStorage {
96
119
  }
97
120
  }
98
121
 
122
+ /**
123
+ *
124
+ * @template T
125
+ * @param {{():T}} fn
126
+ * @returns {Promise<T>}
127
+ */
128
+ _catchNetworkIssues (fn) {
129
+ return Promise.resolve(fn())
130
+ .catch((e) => {
131
+ this._detectNetworkIssueException(e);
132
+ throw e;
133
+ });
134
+ }
135
+
136
+ /**
137
+ * @template {Error} T
138
+ * @param {T} e
139
+ * @returns {T}
140
+ */
141
+ _detectNetworkIssueException (e) {
142
+ if (BaseStorage.netFailuresCount !== 0
143
+ && BaseStorage.networkFailureErrorNames.includes(e.name)) {
144
+
145
+ const now = Date.now();
146
+ BaseStorage._failStack.push(now);
147
+
148
+ if (BaseStorage._failStack.length >= BaseStorage.netFailuresCount
149
+ && BaseStorage._failStack.shift() > (now - BaseStorage.netFailuresIntervalMs)
150
+ && BaseStorage._killing === null) {
151
+
152
+ this._log.error(`${this._collectionName}: KILLING APP DUE FREQUENT NETWORK ERRORS ${BaseStorage._failStack.length}`, e);
153
+
154
+ // let it alive for following ten seconds to process all logs
155
+ BaseStorage._killing = BaseStorage.killer() || null;
156
+ }
157
+ }
158
+ return e;
159
+ }
160
+
99
161
  preHeat () {
100
162
  return this._getCollection();
101
163
  }
@@ -201,6 +263,7 @@ class BaseStorage {
201
263
  this._collection = c;
202
264
  } catch (e) {
203
265
  this._collection = null;
266
+ this._detectNetworkIssueException(e);
204
267
  throw e;
205
268
  }
206
269
  }
@@ -37,7 +37,7 @@ class StateStorage extends BaseStorage {
37
37
  * @param {Db|{():Promise<Db>}} mongoDb
38
38
  * @param {string} collectionName
39
39
  * @param {{error:Function,log:Function}} [log] - console like logger
40
- * @param {boolean} isCosmo
40
+ * @param {boolean|number} isCosmo - boolean or number of failures in last 10min to kill app
41
41
  */
42
42
  constructor (mongoDb, collectionName = 'states', log = defaultLogger, isCosmo = false) {
43
43
  super(mongoDb, collectionName, log, isCosmo);
@@ -62,7 +62,6 @@ class StateStorage extends BaseStorage {
62
62
  { name: SEARCH }
63
63
  );
64
64
  }
65
-
66
65
  }
67
66
 
68
67
  /**
@@ -101,7 +100,6 @@ class StateStorage extends BaseStorage {
101
100
  */
102
101
  async getOrCreateAndLock (senderId, pageId, defaultState = {}, timeout = 300) {
103
102
  const now = Date.now();
104
-
105
103
  const c = await this._getCollection();
106
104
 
107
105
  const $setOnInsert = {
@@ -116,7 +114,7 @@ class StateStorage extends BaseStorage {
116
114
 
117
115
  const $lt = now - timeout;
118
116
 
119
- const res = await c.findOneAndUpdate({
117
+ const res = await this._catchNetworkIssues(() => c.findOneAndUpdate({
120
118
  senderId,
121
119
  pageId,
122
120
  lock: { $lt }
@@ -129,7 +127,7 @@ class StateStorage extends BaseStorage {
129
127
  projection: {
130
128
  _id: 0
131
129
  }
132
- });
130
+ }));
133
131
 
134
132
  return res.value;
135
133
  }