keuss 2.0.7 → 2.2.0

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/backends/mongo.js CHANGED
@@ -1,10 +1,12 @@
1
- var _ = require ('lodash');
1
+ const _ = require ('lodash');
2
2
 
3
- var MongoClient = require ('mongodb').MongoClient;
4
- var mongo = require ('mongodb');
3
+ const MongoClient = require ('mongodb').MongoClient;
4
+ const mongo = require ('mongodb');
5
+ const debug = require('debug')('keuss:Queue:mongo');
6
+
7
+ const Queue = require ('../Queue');
8
+ const QFactory_MongoDB_defaults = require ('../QFactory-MongoDB-defaults');
5
9
 
6
- var Queue = require ('../Queue');
7
- var QFactory_MongoDB_defaults = require ('../QFactory-MongoDB-defaults');
8
10
 
9
11
  class SimpleMongoQueue extends Queue {
10
12
 
@@ -20,187 +22,237 @@ class SimpleMongoQueue extends Queue {
20
22
  return 'mongo:simple';
21
23
  }
22
24
 
25
+
23
26
  /////////////////////////////////////////
24
27
  type () {
25
28
  return 'mongo:simple';
26
29
  }
27
30
 
31
+
28
32
  /////////////////////////////////////////
29
33
  // add element to queue
30
- insert (entry, callback) {
31
- this._col.insertOne (entry, {}, (err, result) => {
32
- if (err) return callback (err);
33
- callback (null, result.insertedId);
34
+ insert (entry, cb) {
35
+ this._col.insertOne (entry)
36
+ .then (res => {
37
+ debug ('inserted entry %j -> %j', entry, res)
38
+ cb (null, res.insertedId);
39
+ })
40
+ .catch (err => {
41
+ if (err.code == 11000) {
42
+ const e = new Error (`duplicated entry with _id ${entry._id}`)
43
+ e.code = 'EDUP';
44
+ cb(e)
45
+ }
46
+ else {
47
+ cb (err)
48
+ }
34
49
  });
35
50
  }
36
-
51
+ c
37
52
 
38
53
  /////////////////////////////////////////
39
54
  // get element from queue
40
- get (callback) {
41
- this._col.findOneAndDelete ({mature: {$lte: Queue.nowPlusSecs (0)}}, {sort: {mature : 1}}, (err, result) => {
42
- if (err) return callback (err);
55
+ get (cb) {
56
+ const query = {
57
+ mature: {$lte: Queue.nowPlusSecs (0)}
58
+ };
59
+
60
+ const opts = {
61
+ sort: {mature : 1},
62
+ includeResultMetadata: true
63
+ };
64
+
65
+ this._col.findOneAndDelete (query, opts)
66
+ .then (result => {
67
+ debug ('get() element, findOneAndDelete returned %j', result)
43
68
  const v = result && result.value;
44
- if (!v) return callback ();
69
+ if (!v) return cb ();
45
70
  if (v.payload._bsontype == 'Binary') v.payload = v.payload.buffer;
46
- callback (null, v);
47
- });
71
+ cb (null, v);
72
+ })
73
+ .catch (cb);
48
74
  }
49
-
75
+
50
76
 
51
77
  //////////////////////////////////
52
78
  // reserve element: call cb (err, pl) where pl has an id
53
- reserve (callback) {
54
- var delay = this._opts.reserve_delay || 120;
79
+ reserve (cb) {
80
+ const delay = this._opts.reserve_delay || 120;
55
81
 
56
- var query = {
82
+ const query = {
57
83
  mature: {$lte: Queue.nowPlusSecs (0)}
58
84
  };
59
85
 
60
- var update = {
86
+ const update = {
61
87
  $set: {mature: Queue.nowPlusSecs (delay), reserved: new Date ()},
62
88
  $inc: {tries: 1}
63
89
  };
64
90
 
65
- var opts = {
91
+ const opts = {
66
92
  sort: {mature : 1},
67
- returnDocument: 'before'
93
+ returnDocument: 'before',
94
+ includeResultMetadata: true
68
95
  };
69
96
 
70
- this._col.findOneAndUpdate (query, update, opts, (err, result) => {
71
- if (err) return callback (err);
72
- const v = result && result.value;
73
- if (!v) return callback ();
97
+ this._col.findOneAndUpdate (query, update, opts)
98
+ .then (res => {
99
+ debug ('reserve() element, findOneAndUpdate returned %j', res)
100
+ const v = res && res.value;
101
+ if (!v) return cb ();
74
102
  if (v.payload._bsontype == 'Binary') v.payload = v.payload.buffer;
75
- callback (null, v);
76
- });
103
+ cb (null, v);
104
+ })
105
+ .catch (cb);
77
106
  }
78
107
 
79
108
 
80
109
  //////////////////////////////////
81
110
  // commit previous reserve, by p.id
82
- commit (id, callback) {
111
+ commit (id, cb) {
112
+ const query = {
113
+ reserved: {$exists: true}
114
+ };
115
+
83
116
  try {
84
- var query = {
85
- _id: (_.isString(id) ? new mongo.ObjectID (id) : id),
86
- reserved: {$exists: true}
87
- };
117
+ query._id = (_.isString(id) ? new mongo.ObjectId (id) : id);
88
118
  }
89
119
  catch (e) {
90
- return callback ('id [' + id + '] can not be used as rollback id: ' + e);
120
+ return cb ('id [' + id + '] can not be used as rollback id: ' + e);
91
121
  }
92
122
 
93
- this._col.deleteOne (query, {}, (err, result) => {
94
- if (err) return callback (err);
95
- callback (null, result && (result.deletedCount == 1));
96
- });
123
+ this._col.deleteOne (query, {})
124
+ .then (res => {
125
+ debug ('commit(%s) element, deleteOne returned %j', id, res)
126
+ cb (null, res && (res.deletedCount == 1));
127
+ })
128
+ .catch (cb);
97
129
  }
98
130
 
99
131
 
100
132
  //////////////////////////////////
101
133
  // rollback previous reserve, by p.id
102
- rollback (id, next_t, callback) {
134
+ rollback (id, next_t, cb) {
103
135
  if (_.isFunction (next_t)) {
104
- callback = next_t;
136
+ cb = next_t;
105
137
  next_t = null;
106
138
  }
107
139
 
140
+ const query = {
141
+ reserved: {$exists: true}
142
+ };
143
+
108
144
  try {
109
- var query = {
110
- _id: (_.isString(id) ? new mongo.ObjectID (id) : id),
111
- reserved: {$exists: true}
112
- };
145
+ query ._id = (_.isString(id) ? new mongo.ObjectId (id) : id);
113
146
  }
114
147
  catch (e) {
115
- return callback ('id [' + id + '] can not be used as rollback id: ' + e);
148
+ return cb ('id [' + id + '] can not be used as rollback id: ' + e);
116
149
  }
117
150
 
118
- var update = {
151
+ const update = {
119
152
  $set: {mature: (next_t ? new Date (next_t) : Queue.now ())},
120
153
  $unset: {reserved: ''}
121
154
  };
122
155
 
123
- this._col.updateOne (query, update, {}, (err, result) => {
124
- if (err) return callback (err);
125
- callback (null, result && (result.modifiedCount == 1));
126
- });
156
+ this._col.updateOne (query, update, {})
157
+ .then (res => {
158
+ debug ('rollback(%s) element, updateOne returned %j', id, res)
159
+ cb (null, res && (res.modifiedCount == 1));
160
+ })
161
+ .catch (cb);
127
162
  }
128
163
 
129
164
 
130
165
  //////////////////////////////////
131
166
  // queue size including non-mature elements
132
- totalSize (callback) {
133
- var q = {};
134
- var opts = {};
135
- this._col.countDocuments (q, opts, callback);
167
+ totalSize (cb) {
168
+ const q = {};
169
+ const opts = {};
170
+ this._col.countDocuments (q, opts)
171
+ .then (res => cb (null, res))
172
+ .catch (cb);
136
173
  }
137
174
 
138
175
 
139
176
  //////////////////////////////////
140
177
  // queue size NOT including non-mature elements
141
- size (callback) {
142
- var q = {
178
+ size (cb) {
179
+ const q = {
143
180
  mature : {$lte : Queue.now ()}
144
181
  };
145
182
 
146
- var opts = {};
147
- this._col.countDocuments (q, opts, callback);
183
+ const opts = {};
184
+ this._col.countDocuments (q, opts)
185
+ .then (res => cb (null, res))
186
+ .catch (cb);
148
187
  }
149
188
 
150
189
 
151
190
  //////////////////////////////////
152
191
  // queue size of non-mature elements only
153
- schedSize (callback) {
154
- var q = {
192
+ schedSize (cb) {
193
+ const q = {
155
194
  mature : {$gt : Queue.now ()},
156
195
  reserved: {$exists: false}
157
196
  };
158
197
 
159
- var opts = {};
160
- this._col.countDocuments (q, opts, callback);
198
+ const opts = {};
199
+ this._col.countDocuments (q, opts)
200
+ .then (res => cb (null, res))
201
+ .catch (cb);
161
202
  }
162
203
 
163
204
 
164
205
  //////////////////////////////////
165
206
  // queue size of reserved elements only
166
- resvSize (callback) {
167
- var q = {
207
+ resvSize (cb) {
208
+ const q = {
168
209
  mature : {$gt : Queue.now ()},
169
210
  reserved: {$exists: true}
170
211
  };
171
212
 
172
- var opts = {};
173
- this._col.countDocuments (q, opts, callback);
213
+ const opts = {};
214
+ this._col.countDocuments (q, opts)
215
+ .then (res => cb (null, res))
216
+ .catch (cb);
174
217
  }
175
218
 
176
219
 
177
220
  /////////////////////////////////////////
178
221
  // get element from queue
179
- next_t (callback) {
180
- this._col.find ({}).limit(1).sort ({mature:1}).project ({mature:1}).next ((err, result) => {
181
- if (err) return callback (err);
182
- callback (null, result && result.mature);
183
- });
222
+ next_t (cb) {
223
+ this._col.find ({})
224
+ .limit(1)
225
+ .sort ({mature:1})
226
+ .project ({mature:1})
227
+ .next ()
228
+ .then (res => {
229
+ debug ('next_t(), find returned %j', res)
230
+ cb (null, res && res.mature);
231
+ })
232
+ .catch (cb);
184
233
  }
185
234
 
186
235
 
187
236
  //////////////////////////////////////////////
188
237
  // remove by id
189
- remove (id, callback) {
238
+ remove (id, cb) {
239
+ const query = {
240
+ reserved: {$exists: false}
241
+ };
242
+
190
243
  try {
191
- var query = {
192
- _id: (_.isString(id) ? new mongo.ObjectID (id) : id),
193
- reserved: {$exists: false}
194
- };
244
+ query._id = (_.isString(id) ? new mongo.ObjectId (id) : id);
195
245
  }
196
246
  catch (e) {
197
- return callback ('id [' + id + '] can not be used as remove id: ' + e);
247
+ return cb ('id [' + id + '] can not be used as remove id: ' + e);
198
248
  }
199
249
 
200
- this._col.deleteOne (query, {}, (err, result) => {
201
- if (err) return callback (err);
202
- callback (null, result && (result.deletedCount == 1));
203
- });
250
+ this._col.deleteOne (query, {})
251
+ .then (res => {
252
+ debug ('remove(%s) element, deleteOne returned %j', id, res)
253
+ cb (null, res && (res.deletedCount == 1));
254
+ })
255
+ .catch (cb)
204
256
  }
205
257
 
206
258
 
@@ -210,11 +262,14 @@ class SimpleMongoQueue extends Queue {
210
262
  //////////////////////////////////////////////////////////////////
211
263
  // create needed indexes for O(1) functioning
212
264
  _ensureIndexes (cb) {
213
- this._col.createIndex ({mature : 1}, err => cb (err, this));
265
+ this._col.createIndex ({mature : 1})
266
+ .then (() => cb (null, this))
267
+ .catch (cb);
214
268
  }
215
269
  };
216
270
 
217
271
 
272
+ ///////////////////////////////////////////////////////////////////////////////
218
273
  class Factory extends QFactory_MongoDB_defaults {
219
274
  constructor (opts, mongo_conn) {
220
275
  super (opts);
@@ -256,25 +311,22 @@ class Factory extends QFactory_MongoDB_defaults {
256
311
  reserve: true,
257
312
  pipeline: false,
258
313
  tape: false,
259
- remove: true
314
+ remove: true,
315
+ id: true,
260
316
  };
261
317
  }
262
318
  }
263
319
 
264
320
  function creator (opts, cb) {
265
- var _opts = opts || {};
266
- var m_url = _opts.url || 'mongodb://localhost:27017/keuss';
321
+ const _opts = opts || {};
322
+ const m_url = _opts.url || 'mongodb://localhost:27017/keuss';
267
323
 
268
- MongoClient.connect (m_url, { useNewUrlParser: true }, (err, cl) => {
269
- if (err) return cb (err);
270
- var F = new Factory (_opts, cl);
324
+ MongoClient.connect (m_url)
325
+ .then (cl => {
326
+ const F = new Factory (_opts, cl);
271
327
  F.async_init (err => cb (null, F));
272
- });
328
+ })
329
+ .catch (cb);
273
330
  }
274
331
 
275
332
  module.exports = creator;
276
-
277
-
278
-
279
-
280
-
@@ -31,7 +31,8 @@ class Factory extends QFactory_MongoDB_defaults {
31
31
  }
32
32
  }, {
33
33
  upsert: true
34
- });
34
+ })
35
+ .finally (() => {});
35
36
  }
36
37
 
37
38
 
@@ -98,9 +99,8 @@ class Factory extends QFactory_MongoDB_defaults {
98
99
  }
99
100
  }, {
100
101
  upsert: true
101
- });
102
-
103
-
102
+ })
103
+ .finally (() => {});
104
104
  }
105
105
 
106
106
 
@@ -141,11 +141,15 @@ class Factory extends QFactory_MongoDB_defaults {
141
141
  close (cb) {
142
142
  super.close (() => {
143
143
  async.parallel ([
144
- cb => this._mongo_data_conn.close (cb),
145
- cb => this._mongo_topology_conn.close (cb)
146
- ], err => {
144
+ cb => this._mongo_data_conn.close ().then (res => cb (null, res)).catch (cb),
145
+ cb => this._mongo_topology_conn.close ().then (res => cb (null, res)).catch (cb),
146
+ ])
147
+ .then (res => {
147
148
  this._mongo_data_conn = null;
148
149
  this._mongo_topology_conn = null;
150
+ if (cb) return cb ();
151
+ })
152
+ .catch (err => {
149
153
  if (cb) return cb (err);
150
154
  });
151
155
  });
@@ -165,7 +169,8 @@ class Factory extends QFactory_MongoDB_defaults {
165
169
  reserve: true,
166
170
  pipeline: true,
167
171
  tape: false,
168
- remove: true
172
+ remove: true,
173
+ id: true,
169
174
  };
170
175
  }
171
176
 
@@ -194,30 +199,14 @@ function creator (opts, cb) {
194
199
  }
195
200
 
196
201
  async.series ([
197
- cb => MongoClient.connect (m_url, { useNewUrlParser: true }, (err, cl) => {
198
- if (err) {
199
- debug ('error while connecting to data mongoDB [%s]', m_url, err);
200
- return cb (err);
201
- }
202
-
203
- debug ('connected OK to data mongoDB %s', m_url);
204
- cb (null, cl);
205
- }),
206
- cb => MongoClient.connect (m_topology_url, { useNewUrlParser: true }, (err, cl) => {
207
- if (err) {
208
- debug ('error while connecting to topology mongoDB [%s]', m_topology_url, err);
209
- return cb (err);
210
- }
211
-
212
- debug ('connected OK to topology mongoDB %s', m_topology_url);
213
- cb (null, cl);
214
- }),
215
- ], (err, res) => {
216
- if (err) return cb (err);
217
-
218
- var F = new Factory (_opts, res[0], res[1]);
202
+ cb => MongoClient.connect (m_url).then (res => cb (null, res)).catch (cb),
203
+ cb => MongoClient.connect (m_topology_url).then (res => cb (null, res)).catch (cb),
204
+ ])
205
+ .then (res => {
206
+ const F = new Factory (_opts, res[0], res[1]);
219
207
  F.async_init (err => cb (null, F));
220
- });
208
+ })
209
+ .catch (cb);
221
210
  }
222
211
 
223
212
  module.exports = creator;
@@ -58,7 +58,7 @@ class PGQueue extends Queue {
58
58
  /////////////////////////////////////////
59
59
  // add element to queue
60
60
  insert (entry, cb) {
61
- const _id = entry.id || uuid.v4();
61
+ const _id = entry._id || uuid.v4();
62
62
  const tries = entry.tries || 0;
63
63
  const mature = new Date (entry.mature);
64
64
 
@@ -73,7 +73,19 @@ class PGQueue extends Queue {
73
73
  }
74
74
 
75
75
  this._pool.query (`INSERT INTO ${this._tbl_name} VALUES($1, $2, $3, $4)`, [_id, pl, mature, tries], (err, res) => {
76
- if (err) return cb (err);
76
+ if (err) {
77
+ if (err.code == '23505') {
78
+ const e = new Error (`duplicated entry with _id ${entry._id}`)
79
+ e.code = 'EDUP';
80
+ cb(e)
81
+ }
82
+ else {
83
+ cb (err)
84
+ }
85
+
86
+ return;
87
+ }
88
+
77
89
  cb (null, _id)
78
90
  })
79
91
  }
@@ -353,7 +365,8 @@ class Factory extends QFactory {
353
365
  reserve: true,
354
366
  pipeline: false,
355
367
  tape: false,
356
- remove: true
368
+ remove: true,
369
+ id: true,
357
370
  };
358
371
  }
359
372
  }