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/.mocharc.yaml +3 -0
- package/Pipeline/BaseLink.js +1 -1
- package/Pipeline/Queue.js +114 -89
- package/Queue.js +15 -2
- package/backends/bucket-mongo-safe.js +166 -145
- package/backends/intraorder.js +94 -83
- package/backends/mongo.js +147 -95
- package/backends/pl-mongo.js +20 -31
- package/backends/postgres.js +16 -3
- package/backends/ps-mongo.js +131 -110
- package/backends/redis-list.js +2 -1
- package/backends/redis-oq.js +2 -3
- package/backends/stream-mongo.js +83 -64
- package/lib/mubsub/channel.js +313 -0
- package/lib/mubsub/connection.js +79 -0
- package/lib/mubsub/index.js +10 -0
- package/package.json +5 -7
- package/signal/mongo-capped.js +1 -1
- package/stats/mongo.js +91 -54
- package/utils/RedisOrderedQueue.js +23 -3
package/backends/ps-mongo.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
const async = require ('async');
|
|
2
|
+
const _ = require ('lodash');
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
const MongoClient = require ('mongodb').MongoClient;
|
|
5
|
+
const mongo = require ('mongodb');
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
const Queue = require ('../Queue');
|
|
8
|
+
const QFactory_MongoDB_defaults = require ('../QFactory-MongoDB-defaults');
|
|
9
9
|
|
|
10
10
|
|
|
11
|
+
//////////////////////////////////////////////
|
|
11
12
|
class PersistentMongoQueue extends Queue {
|
|
12
|
-
|
|
13
13
|
//////////////////////////////////////////////
|
|
14
14
|
constructor (name, factory, opts, orig_opts) {
|
|
15
15
|
super (name, factory, opts, orig_opts);
|
|
@@ -32,54 +32,64 @@ class PersistentMongoQueue extends Queue {
|
|
|
32
32
|
|
|
33
33
|
/////////////////////////////////////////
|
|
34
34
|
// add element to queue
|
|
35
|
-
insert (entry,
|
|
36
|
-
this._col.insertOne (entry, {}
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
insert (entry, cb) {
|
|
36
|
+
this._col.insertOne (entry, {})
|
|
37
|
+
.then (res => cb (null, res.insertedId))
|
|
38
|
+
.catch (err => {
|
|
39
|
+
if (err.code == 11000) {
|
|
40
|
+
const e = new Error (`duplicated entry with _id ${entry._id}`)
|
|
41
|
+
e.code = 'EDUP';
|
|
42
|
+
cb(e)
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
cb (err)
|
|
46
|
+
}
|
|
39
47
|
});
|
|
40
48
|
}
|
|
41
49
|
|
|
42
50
|
|
|
43
51
|
/////////////////////////////////////////
|
|
44
52
|
// get element from queue
|
|
45
|
-
get (
|
|
46
|
-
|
|
53
|
+
get (cb) {
|
|
54
|
+
const q = {
|
|
47
55
|
mature: {$lte: Queue.nowPlusSecs (0)},
|
|
48
56
|
processed: {$exists: false}
|
|
49
57
|
};
|
|
50
58
|
|
|
51
|
-
|
|
59
|
+
const updt = {
|
|
52
60
|
$set: {
|
|
53
61
|
processed: new Date (),
|
|
54
62
|
mature: Queue.nowPlusSecs (100 * this._opts.ttl)
|
|
55
63
|
}
|
|
56
64
|
};
|
|
57
65
|
|
|
58
|
-
|
|
59
|
-
sort: {mature : 1}
|
|
66
|
+
const opts = {
|
|
67
|
+
sort: {mature : 1},
|
|
68
|
+
includeResultMetadata: true
|
|
60
69
|
};
|
|
61
70
|
|
|
62
|
-
this._col.findOneAndUpdate (q, updt, opts
|
|
63
|
-
|
|
64
|
-
const v =
|
|
65
|
-
if (!v) return
|
|
71
|
+
this._col.findOneAndUpdate (q, updt, opts)
|
|
72
|
+
.then (res => {
|
|
73
|
+
const v = res && res.value;
|
|
74
|
+
if (!v) return cb ();
|
|
66
75
|
if (v.payload._bsontype == 'Binary') v.payload = v.payload.buffer;
|
|
67
|
-
|
|
68
|
-
})
|
|
76
|
+
cb (null, v);
|
|
77
|
+
})
|
|
78
|
+
.catch (cb)
|
|
69
79
|
}
|
|
70
80
|
|
|
71
81
|
|
|
72
82
|
//////////////////////////////////
|
|
73
83
|
// reserve element: call cb (err, pl) where pl has an id
|
|
74
|
-
reserve (
|
|
75
|
-
|
|
84
|
+
reserve (cb) {
|
|
85
|
+
const delay = this._opts.reserve_delay || 120;
|
|
76
86
|
|
|
77
|
-
|
|
87
|
+
const query = {
|
|
78
88
|
processed: {$exists: false},
|
|
79
89
|
mature: {$lte: Queue.nowPlusSecs (0)}
|
|
80
90
|
};
|
|
81
91
|
|
|
82
|
-
|
|
92
|
+
const update = {
|
|
83
93
|
$set: {
|
|
84
94
|
mature: Queue.nowPlusSecs (delay),
|
|
85
95
|
reserved: new Date ()
|
|
@@ -87,37 +97,38 @@ class PersistentMongoQueue extends Queue {
|
|
|
87
97
|
$inc: {tries: 1}
|
|
88
98
|
};
|
|
89
99
|
|
|
90
|
-
|
|
100
|
+
const opts = {
|
|
91
101
|
sort: {mature : 1},
|
|
92
|
-
returnDocument: 'before'
|
|
102
|
+
returnDocument: 'before',
|
|
103
|
+
includeResultMetadata: true
|
|
93
104
|
};
|
|
94
105
|
|
|
95
|
-
this._col.findOneAndUpdate (query, update, opts
|
|
96
|
-
|
|
97
|
-
const v =
|
|
98
|
-
if (!v) return
|
|
106
|
+
this._col.findOneAndUpdate (query, update, opts)
|
|
107
|
+
.then (res => {
|
|
108
|
+
const v = res && res.value;
|
|
109
|
+
if (!v) return cb ();
|
|
99
110
|
if (v.payload._bsontype == 'Binary') v.payload = v.payload.buffer;
|
|
100
|
-
|
|
101
|
-
})
|
|
111
|
+
cb (null, v);
|
|
112
|
+
})
|
|
113
|
+
.catch (cb);
|
|
102
114
|
}
|
|
103
115
|
|
|
104
116
|
|
|
105
117
|
//////////////////////////////////
|
|
106
118
|
// commit previous reserve, by p.id
|
|
107
|
-
commit (id,
|
|
108
|
-
|
|
119
|
+
commit (id, cb) {
|
|
120
|
+
const query = {
|
|
121
|
+
reserved: {$exists: true}
|
|
122
|
+
};
|
|
109
123
|
|
|
110
124
|
try {
|
|
111
|
-
query =
|
|
112
|
-
_id: (_.isString(id) ? new mongo.ObjectID (id) : id),
|
|
113
|
-
reserved: {$exists: true}
|
|
114
|
-
};
|
|
125
|
+
query._id = (_.isString(id) ? new mongo.ObjectId (id) : id);
|
|
115
126
|
}
|
|
116
127
|
catch (e) {
|
|
117
|
-
return
|
|
128
|
+
return cb ('id [' + id + '] can not be used as rollback id: ' + e);
|
|
118
129
|
}
|
|
119
130
|
|
|
120
|
-
|
|
131
|
+
const updt = {
|
|
121
132
|
$set: {
|
|
122
133
|
processed: new Date (),
|
|
123
134
|
mature: Queue.nowPlusSecs (100 * this._opts.ttl)
|
|
@@ -125,115 +136,121 @@ class PersistentMongoQueue extends Queue {
|
|
|
125
136
|
$unset: {reserved: ''}
|
|
126
137
|
};
|
|
127
138
|
|
|
128
|
-
|
|
139
|
+
const opts = {};
|
|
129
140
|
|
|
130
|
-
this._col.updateOne (query, updt, opts
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
});
|
|
141
|
+
this._col.updateOne (query, updt, opts)
|
|
142
|
+
.then (res => cb (null, res && (res.modifiedCount == 1)))
|
|
143
|
+
.catch (cb);
|
|
134
144
|
}
|
|
135
145
|
|
|
136
146
|
|
|
137
147
|
//////////////////////////////////
|
|
138
148
|
// rollback previous reserve, by p.id
|
|
139
|
-
rollback (id, next_t,
|
|
149
|
+
rollback (id, next_t, cb) {
|
|
140
150
|
if (_.isFunction (next_t)) {
|
|
141
|
-
|
|
151
|
+
cb = next_t;
|
|
142
152
|
next_t = null;
|
|
143
153
|
}
|
|
144
154
|
|
|
155
|
+
const query = {
|
|
156
|
+
reserved: {$exists: true}
|
|
157
|
+
};
|
|
158
|
+
|
|
145
159
|
try {
|
|
146
|
-
|
|
147
|
-
_id: (_.isString(id) ? new mongo.ObjectID (id) : id),
|
|
148
|
-
reserved: {$exists: true}
|
|
149
|
-
};
|
|
160
|
+
query._id = (_.isString(id) ? new mongo.ObjectId (id) : id);
|
|
150
161
|
}
|
|
151
162
|
catch (e) {
|
|
152
|
-
return
|
|
163
|
+
return cb ('id [' + id + '] can not be used as rollback id: ' + e);
|
|
153
164
|
}
|
|
154
165
|
|
|
155
|
-
|
|
166
|
+
const update = {
|
|
156
167
|
$set: {mature: (next_t ? new Date (next_t) : Queue.now ())},
|
|
157
168
|
$unset: {reserved: ''}
|
|
158
169
|
};
|
|
159
170
|
|
|
160
|
-
this._col.updateOne (query, update, {}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
});
|
|
171
|
+
this._col.updateOne (query, update, {})
|
|
172
|
+
.then (res => cb (null, res && (res.modifiedCount == 1)))
|
|
173
|
+
.catch (cb);
|
|
164
174
|
}
|
|
165
175
|
|
|
166
176
|
|
|
167
177
|
//////////////////////////////////
|
|
168
178
|
// queue size including non-mature elements
|
|
169
|
-
totalSize (
|
|
170
|
-
|
|
179
|
+
totalSize (cb) {
|
|
180
|
+
const q = {
|
|
171
181
|
processed: {$exists: false}
|
|
172
182
|
};
|
|
173
183
|
|
|
174
|
-
|
|
175
|
-
this._col.countDocuments (q, opts
|
|
184
|
+
const opts = {};
|
|
185
|
+
this._col.countDocuments (q, opts)
|
|
186
|
+
.then (res => cb (null, res))
|
|
187
|
+
.catch (cb);
|
|
176
188
|
}
|
|
177
189
|
|
|
178
190
|
|
|
179
191
|
//////////////////////////////////
|
|
180
192
|
// queue size NOT including non-mature elements
|
|
181
|
-
size (
|
|
182
|
-
|
|
193
|
+
size (cb) {
|
|
194
|
+
const q = {
|
|
183
195
|
processed: {$exists: false},
|
|
184
196
|
mature : {$lte : Queue.now ()}
|
|
185
197
|
};
|
|
186
198
|
|
|
187
|
-
|
|
188
|
-
this._col.countDocuments (q, opts
|
|
199
|
+
const opts = {};
|
|
200
|
+
this._col.countDocuments (q, opts)
|
|
201
|
+
.then (res => cb (null, res))
|
|
202
|
+
.catch (cb);
|
|
189
203
|
}
|
|
190
204
|
|
|
191
205
|
|
|
192
206
|
//////////////////////////////////
|
|
193
207
|
// queue size of non-mature elements only
|
|
194
|
-
schedSize (
|
|
195
|
-
|
|
208
|
+
schedSize (cb) {
|
|
209
|
+
const q = {
|
|
196
210
|
mature : {$gt : Queue.now ()},
|
|
197
211
|
processed: {$exists: false},
|
|
198
212
|
reserved: {$exists: false}
|
|
199
213
|
};
|
|
200
214
|
|
|
201
|
-
|
|
202
|
-
this._col.countDocuments (q, opts
|
|
215
|
+
const opts = {};
|
|
216
|
+
this._col.countDocuments (q, opts)
|
|
217
|
+
.then (res => cb (null, res))
|
|
218
|
+
.catch (cb);
|
|
203
219
|
}
|
|
204
220
|
|
|
205
221
|
|
|
206
222
|
//////////////////////////////////
|
|
207
223
|
// queue size of reserved elements only
|
|
208
|
-
resvSize (
|
|
209
|
-
|
|
224
|
+
resvSize (cb) {
|
|
225
|
+
const q = {
|
|
210
226
|
mature : {$gt : Queue.now ()},
|
|
211
227
|
processed: {$exists: false},
|
|
212
228
|
reserved: {$exists: true}
|
|
213
229
|
};
|
|
214
230
|
|
|
215
|
-
|
|
216
|
-
this._col.countDocuments (q, opts
|
|
231
|
+
const opts = {};
|
|
232
|
+
this._col.countDocuments (q, opts)
|
|
233
|
+
.then (res => cb (null, res))
|
|
234
|
+
.catch (cb);
|
|
217
235
|
}
|
|
218
236
|
|
|
219
237
|
|
|
220
238
|
//////////////////////////////////////////////
|
|
221
239
|
// remove by id
|
|
222
|
-
remove (id,
|
|
223
|
-
|
|
240
|
+
remove (id, cb) {
|
|
241
|
+
const query ={
|
|
242
|
+
processed: {$exists: false},
|
|
243
|
+
reserved: {$exists: false}
|
|
244
|
+
};
|
|
224
245
|
|
|
225
246
|
try {
|
|
226
|
-
query =
|
|
227
|
-
_id: (_.isString(id) ? new mongo.ObjectID (id) : id),
|
|
228
|
-
processed: {$exists: false},
|
|
229
|
-
reserved: {$exists: false}
|
|
230
|
-
};
|
|
247
|
+
query._id = (_.isString(id) ? new mongo.ObjectId (id) : id);
|
|
231
248
|
}
|
|
232
249
|
catch (e) {
|
|
233
|
-
return
|
|
250
|
+
return cb ('id [' + id + '] can not be used as remove id: ' + e);
|
|
234
251
|
}
|
|
235
252
|
|
|
236
|
-
|
|
253
|
+
const updt = {
|
|
237
254
|
$set: {
|
|
238
255
|
processed: new Date (),
|
|
239
256
|
mature: Queue.nowPlusSecs (100 * this._opts.ttl),
|
|
@@ -241,27 +258,25 @@ class PersistentMongoQueue extends Queue {
|
|
|
241
258
|
},
|
|
242
259
|
};
|
|
243
260
|
|
|
244
|
-
|
|
261
|
+
const opts = {};
|
|
245
262
|
|
|
246
|
-
this._col.updateOne (query, updt, opts
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
});
|
|
263
|
+
this._col.updateOne (query, updt, opts)
|
|
264
|
+
.then (res => cb (null, res && (res.modifiedCount == 1)))
|
|
265
|
+
.catch (cb);
|
|
250
266
|
}
|
|
251
267
|
|
|
252
268
|
|
|
253
269
|
/////////////////////////////////////////
|
|
254
270
|
// get element from queue
|
|
255
|
-
next_t (
|
|
271
|
+
next_t (cb) {
|
|
256
272
|
this._col
|
|
257
273
|
.find ({processed: {$exists: false}})
|
|
258
274
|
.limit(1)
|
|
259
275
|
.sort ({mature:1})
|
|
260
276
|
.project ({mature:1})
|
|
261
|
-
.next (
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
});
|
|
277
|
+
.next ()
|
|
278
|
+
.then (res => cb (null, res && res.mature))
|
|
279
|
+
.catch (cb);
|
|
265
280
|
}
|
|
266
281
|
|
|
267
282
|
|
|
@@ -271,14 +286,17 @@ class PersistentMongoQueue extends Queue {
|
|
|
271
286
|
//////////////////////////////////////////////////////////////////
|
|
272
287
|
// create needed indexes for O(1) functioning
|
|
273
288
|
_ensureIndexes (cb) {
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
this._col.createIndex({processed: 1}, {expireAfterSeconds: this._opts.ttl}
|
|
277
|
-
|
|
289
|
+
async.series ([
|
|
290
|
+
cb => this._col.createIndex ({mature : 1}).then (res => cb(null, res)).catch (cb),
|
|
291
|
+
cb => this._col.createIndex ({processed: 1}, {expireAfterSeconds: this._opts.ttl}).then (res => cb(null, res)).catch (cb),
|
|
292
|
+
])
|
|
293
|
+
.then (() => cb (null, this))
|
|
294
|
+
.catch (cb);
|
|
278
295
|
}
|
|
279
296
|
}
|
|
280
297
|
|
|
281
298
|
|
|
299
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
282
300
|
class Factory extends QFactory_MongoDB_defaults {
|
|
283
301
|
constructor (opts, mongo_conn) {
|
|
284
302
|
super (opts);
|
|
@@ -286,6 +304,7 @@ class Factory extends QFactory_MongoDB_defaults {
|
|
|
286
304
|
this._db = mongo_conn.db();
|
|
287
305
|
}
|
|
288
306
|
|
|
307
|
+
//////////////////////////////////////////////////////////////////
|
|
289
308
|
queue (name, opts, cb) {
|
|
290
309
|
if (!cb) {
|
|
291
310
|
cb = opts;
|
|
@@ -298,6 +317,7 @@ class Factory extends QFactory_MongoDB_defaults {
|
|
|
298
317
|
q._ensureIndexes (cb);
|
|
299
318
|
}
|
|
300
319
|
|
|
320
|
+
//////////////////////////////////////////////////////////////////
|
|
301
321
|
close (cb) {
|
|
302
322
|
super.close (() => {
|
|
303
323
|
if (this._mongo_conn) {
|
|
@@ -309,35 +329,36 @@ class Factory extends QFactory_MongoDB_defaults {
|
|
|
309
329
|
});
|
|
310
330
|
}
|
|
311
331
|
|
|
332
|
+
//////////////////////////////////////////////////////////////////
|
|
312
333
|
type () {
|
|
313
334
|
return PersistentMongoQueue.Type ();
|
|
314
335
|
}
|
|
315
336
|
|
|
337
|
+
//////////////////////////////////////////////////////////////////
|
|
316
338
|
capabilities () {
|
|
317
339
|
return {
|
|
318
340
|
sched: true,
|
|
319
341
|
reserve: true,
|
|
320
342
|
pipeline: false,
|
|
321
343
|
tape: true,
|
|
322
|
-
remove: true
|
|
344
|
+
remove: true,
|
|
345
|
+
id: true,
|
|
323
346
|
};
|
|
324
347
|
}
|
|
325
348
|
}
|
|
326
349
|
|
|
350
|
+
|
|
351
|
+
//////////////////////////////////////////////////////////////////
|
|
327
352
|
function creator (opts, cb) {
|
|
328
|
-
|
|
329
|
-
|
|
353
|
+
const _opts = opts || {};
|
|
354
|
+
const m_url = _opts.url || 'mongodb://localhost:27017/keuss';
|
|
330
355
|
|
|
331
|
-
MongoClient.connect (m_url
|
|
332
|
-
|
|
333
|
-
|
|
356
|
+
MongoClient.connect (m_url)
|
|
357
|
+
.then (cl => {
|
|
358
|
+
const F = new Factory (_opts, cl);
|
|
334
359
|
F.async_init (err => cb (null, F));
|
|
335
|
-
})
|
|
360
|
+
})
|
|
361
|
+
.catch (cb);
|
|
336
362
|
}
|
|
337
363
|
|
|
338
364
|
module.exports = creator;
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
package/backends/redis-list.js
CHANGED
package/backends/redis-oq.js
CHANGED
|
@@ -156,7 +156,8 @@ class Factory extends QFactory {
|
|
|
156
156
|
reserve: true,
|
|
157
157
|
pipeline: false,
|
|
158
158
|
tape: false,
|
|
159
|
-
remove: true
|
|
159
|
+
remove: true,
|
|
160
|
+
id: true,
|
|
160
161
|
};
|
|
161
162
|
}
|
|
162
163
|
}
|
|
@@ -171,5 +172,3 @@ function creator (opts, cb) {
|
|
|
171
172
|
}
|
|
172
173
|
|
|
173
174
|
module.exports = creator;
|
|
174
|
-
|
|
175
|
-
|