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/.mocharc.yaml
ADDED
package/Pipeline/BaseLink.js
CHANGED
|
@@ -55,6 +55,7 @@ class BaseLink extends EventEmitter {
|
|
|
55
55
|
/////////////////////////////////////////
|
|
56
56
|
stop () {
|
|
57
57
|
this._src.cancel ();
|
|
58
|
+
debug ('%s: stopped', this._name);
|
|
58
59
|
}
|
|
59
60
|
|
|
60
61
|
|
|
@@ -164,7 +165,6 @@ class BaseLink extends EventEmitter {
|
|
|
164
165
|
}
|
|
165
166
|
catch (e) {
|
|
166
167
|
debug ('catch error, emitting it: ', e);
|
|
167
|
-
console.log ('catch error, emitting it: ', e);
|
|
168
168
|
this.emit (e);
|
|
169
169
|
this._on_error (e, elem, ondata);
|
|
170
170
|
}
|
package/Pipeline/Queue.js
CHANGED
|
@@ -32,125 +32,142 @@ class PipelinedMongoQueue extends Queue {
|
|
|
32
32
|
|
|
33
33
|
/////////////////////////////////////////
|
|
34
34
|
// add element to queue
|
|
35
|
-
insert (entry,
|
|
35
|
+
insert (entry, cb) {
|
|
36
36
|
entry._q = this._name;
|
|
37
37
|
|
|
38
|
-
this._col.insertOne (entry, {}
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
this._col.insertOne (entry, {})
|
|
39
|
+
.then (res => cb (null, res.insertedId))
|
|
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
|
+
}
|
|
41
49
|
});
|
|
42
50
|
}
|
|
43
51
|
|
|
44
52
|
|
|
45
53
|
/////////////////////////////////////////
|
|
46
54
|
// get element from queue
|
|
47
|
-
get (
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
55
|
+
get (cb) {
|
|
56
|
+
const query = {
|
|
57
|
+
_q: this._name,
|
|
58
|
+
mature: {$lte: Queue.nowPlusSecs (0)}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const opts = {
|
|
62
|
+
sort: {mature : 1},
|
|
63
|
+
includeResultMetadata: true
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
this._col.findOneAndDelete (query, opts)
|
|
67
|
+
.then (res => {
|
|
68
|
+
const v = res && res.value;
|
|
69
|
+
if (!v) return cb ();
|
|
52
70
|
if (v.payload._bsontype == 'Binary') v.payload = v.payload.buffer;
|
|
53
|
-
|
|
54
|
-
})
|
|
71
|
+
cb (null, v);
|
|
72
|
+
})
|
|
73
|
+
.catch (cb);
|
|
55
74
|
}
|
|
56
75
|
|
|
57
76
|
|
|
58
77
|
//////////////////////////////////
|
|
59
78
|
// reserve element: call cb (err, pl) where pl has an id
|
|
60
|
-
reserve (
|
|
61
|
-
|
|
79
|
+
reserve (cb) {
|
|
80
|
+
const delay = this._opts.reserve_delay || 120;
|
|
62
81
|
|
|
63
|
-
|
|
82
|
+
const query = {
|
|
64
83
|
_q: this._name,
|
|
65
84
|
mature: {$lte: Queue.nowPlusSecs (0)}
|
|
66
85
|
};
|
|
67
86
|
|
|
68
|
-
|
|
87
|
+
const update = {
|
|
69
88
|
$set: {mature: Queue.nowPlusSecs (delay), reserved: new Date ()},
|
|
70
89
|
$inc: {tries: 1}
|
|
71
90
|
};
|
|
72
91
|
|
|
73
|
-
|
|
92
|
+
const opts = {
|
|
74
93
|
sort: {mature : 1},
|
|
75
|
-
returnDocument: 'before'
|
|
94
|
+
returnDocument: 'before',
|
|
95
|
+
includeResultMetadata: true
|
|
76
96
|
};
|
|
77
97
|
|
|
78
|
-
this._col.findOneAndUpdate (query, update, opts
|
|
79
|
-
|
|
80
|
-
const v =
|
|
81
|
-
if (!v) return
|
|
98
|
+
this._col.findOneAndUpdate (query, update, opts)
|
|
99
|
+
.then (res => {
|
|
100
|
+
const v = res && res.value;
|
|
101
|
+
if (!v) return cb ();
|
|
82
102
|
if (v.payload._bsontype == 'Binary') v.payload = v.payload.buffer;
|
|
83
|
-
|
|
84
|
-
})
|
|
103
|
+
cb (null, v);
|
|
104
|
+
})
|
|
105
|
+
.catch (cb);
|
|
85
106
|
}
|
|
86
107
|
|
|
87
108
|
|
|
88
109
|
//////////////////////////////////
|
|
89
110
|
// commit previous reserve, by p.id
|
|
90
|
-
commit (id,
|
|
91
|
-
|
|
111
|
+
commit (id, cb) {
|
|
112
|
+
const query = {
|
|
113
|
+
_q: this._name,
|
|
114
|
+
reserved: {$exists: true}
|
|
115
|
+
}
|
|
92
116
|
|
|
93
117
|
try {
|
|
94
|
-
query =
|
|
95
|
-
_id: (_.isString(id) ? new mongo.ObjectID (id) : id),
|
|
96
|
-
_q: this._name,
|
|
97
|
-
reserved: {$exists: true}
|
|
98
|
-
};
|
|
118
|
+
query._id = (_.isString(id) ? new mongo.ObjectId (id) : id);
|
|
99
119
|
}
|
|
100
120
|
catch (e) {
|
|
101
|
-
return
|
|
121
|
+
return cb ('id [' + id + '] can not be used as rollback id: ' + e);
|
|
102
122
|
}
|
|
103
123
|
|
|
104
|
-
this._col.deleteOne (query, {}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
});
|
|
124
|
+
this._col.deleteOne (query, {})
|
|
125
|
+
.then (res => cb (null, res && (res.deletedCount == 1)))
|
|
126
|
+
.catch (cb);
|
|
108
127
|
}
|
|
109
128
|
|
|
110
129
|
|
|
111
130
|
//////////////////////////////////
|
|
112
131
|
// rollback previous reserve, by p.id
|
|
113
|
-
rollback (id, next_t,
|
|
132
|
+
rollback (id, next_t, cb) {
|
|
114
133
|
if (_.isFunction (next_t)) {
|
|
115
|
-
|
|
134
|
+
cb = next_t;
|
|
116
135
|
next_t = null;
|
|
117
136
|
}
|
|
118
137
|
|
|
119
|
-
|
|
138
|
+
const query = {
|
|
139
|
+
_q: this._name,
|
|
140
|
+
reserved: {$exists: true}
|
|
141
|
+
}
|
|
120
142
|
|
|
121
143
|
try {
|
|
122
|
-
query =
|
|
123
|
-
_id: (_.isString(id) ? new mongo.ObjectID (id) : id),
|
|
124
|
-
_q: this._name,
|
|
125
|
-
reserved: {$exists: true}
|
|
126
|
-
};
|
|
144
|
+
query._id = (_.isString(id) ? new mongo.ObjectId (id) : id);
|
|
127
145
|
}
|
|
128
146
|
catch (e) {
|
|
129
|
-
return
|
|
147
|
+
return cb ('id [' + id + '] can not be used as rollback id: ' + e);
|
|
130
148
|
}
|
|
131
149
|
|
|
132
|
-
|
|
150
|
+
const update = {
|
|
133
151
|
$set: {mature: (next_t ? new Date (next_t) : Queue.now ())},
|
|
134
152
|
$unset: {reserved: ''}
|
|
135
153
|
};
|
|
136
154
|
|
|
137
|
-
this._col.updateOne (query, update, {}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
});
|
|
155
|
+
this._col.updateOne (query, update, {})
|
|
156
|
+
.then (res => cb (null, res && (res.modifiedCount == 1)))
|
|
157
|
+
.catch (cb);
|
|
141
158
|
}
|
|
142
159
|
|
|
143
160
|
|
|
144
161
|
//////////////////////////////////
|
|
145
162
|
// passes element to the next queue in pipeline
|
|
146
|
-
pl_step (id, next_queue, opts,
|
|
147
|
-
|
|
163
|
+
pl_step (id, next_queue, opts, cb) {
|
|
164
|
+
const q = {
|
|
148
165
|
_id: id,
|
|
149
166
|
_q: this._name,
|
|
150
167
|
reserved: {$exists: true}
|
|
151
168
|
};
|
|
152
169
|
|
|
153
|
-
|
|
170
|
+
const upd = {
|
|
154
171
|
$set: {
|
|
155
172
|
mature: opts.mature || Queue.now (),
|
|
156
173
|
tries: opts.tries || 0,
|
|
@@ -170,93 +187,101 @@ class PipelinedMongoQueue extends Queue {
|
|
|
170
187
|
_.each (opts.hdrs, (v, k) => upd.$set['hdrs.' + k] = v);
|
|
171
188
|
}
|
|
172
189
|
|
|
173
|
-
this._col.updateOne (q, upd, {}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
});
|
|
190
|
+
this._col.updateOne (q, upd, {})
|
|
191
|
+
.then (res => cb (null, res && (res.modifiedCount == 1)))
|
|
192
|
+
.catch (cb);
|
|
177
193
|
}
|
|
178
194
|
|
|
179
195
|
|
|
180
196
|
//////////////////////////////////
|
|
181
197
|
// queue size including non-mature elements
|
|
182
|
-
totalSize (
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
this._col.countDocuments (q, opts
|
|
198
|
+
totalSize (cb) {
|
|
199
|
+
const q = {_q: this._name};
|
|
200
|
+
const opts = {};
|
|
201
|
+
this._col.countDocuments (q, opts)
|
|
202
|
+
.then (res => cb (null, res))
|
|
203
|
+
.catch (cb);
|
|
186
204
|
}
|
|
187
205
|
|
|
188
206
|
|
|
189
207
|
//////////////////////////////////
|
|
190
208
|
// queue size NOT including non-mature elements
|
|
191
|
-
size (
|
|
192
|
-
|
|
209
|
+
size (cb) {
|
|
210
|
+
const q = {
|
|
193
211
|
_q: this._name,
|
|
194
212
|
mature : {$lte : Queue.now ()}
|
|
195
213
|
};
|
|
196
214
|
|
|
197
|
-
|
|
198
|
-
this._col.countDocuments (q, opts
|
|
215
|
+
const opts = {};
|
|
216
|
+
this._col.countDocuments (q, opts)
|
|
217
|
+
.then (res => cb (null, res))
|
|
218
|
+
.catch (cb);
|
|
199
219
|
}
|
|
200
220
|
|
|
201
221
|
|
|
202
222
|
//////////////////////////////////
|
|
203
223
|
// queue size of non-mature elements only
|
|
204
|
-
schedSize (
|
|
205
|
-
|
|
224
|
+
schedSize (cb) {
|
|
225
|
+
const q = {
|
|
206
226
|
_q: this._name,
|
|
207
227
|
mature : {$gt : Queue.now ()},
|
|
208
228
|
reserved: {$exists: false}
|
|
209
229
|
};
|
|
210
230
|
|
|
211
|
-
|
|
212
|
-
this._col.countDocuments (q, opts
|
|
231
|
+
const opts = {};
|
|
232
|
+
this._col.countDocuments (q, opts)
|
|
233
|
+
.then (res => cb (null, res))
|
|
234
|
+
.catch (cb);
|
|
213
235
|
}
|
|
214
236
|
|
|
215
237
|
|
|
216
238
|
//////////////////////////////////
|
|
217
239
|
// queue size of reserved elements only
|
|
218
|
-
resvSize (
|
|
219
|
-
|
|
240
|
+
resvSize (cb) {
|
|
241
|
+
const q = {
|
|
220
242
|
_q: this._name,
|
|
221
243
|
mature : {$gt : Queue.now ()},
|
|
222
244
|
reserved: {$exists: true}
|
|
223
245
|
};
|
|
224
246
|
|
|
225
|
-
|
|
226
|
-
this._col.countDocuments (q, opts
|
|
247
|
+
const opts = {};
|
|
248
|
+
this._col.countDocuments (q, opts)
|
|
249
|
+
.then (res => cb (null, res))
|
|
250
|
+
.catch (cb);
|
|
227
251
|
}
|
|
228
252
|
|
|
229
253
|
|
|
230
254
|
/////////////////////////////////////////
|
|
231
255
|
// get element from queue
|
|
232
|
-
next_t (
|
|
233
|
-
this._col.find ({_q: this._name})
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
})
|
|
256
|
+
next_t (cb) {
|
|
257
|
+
this._col.find ({_q: this._name})
|
|
258
|
+
.limit(1)
|
|
259
|
+
.sort ({mature:1})
|
|
260
|
+
.project ({mature:1})
|
|
261
|
+
.next ()
|
|
262
|
+
.then (res => cb (null, res && res.mature))
|
|
263
|
+
.catch (cb);
|
|
237
264
|
}
|
|
238
265
|
|
|
239
266
|
|
|
240
267
|
//////////////////////////////////////////////
|
|
241
268
|
// remove by id
|
|
242
|
-
remove (id,
|
|
243
|
-
|
|
269
|
+
remove (id, cb) {
|
|
270
|
+
const query = {
|
|
271
|
+
_q: this._name,
|
|
272
|
+
reserved: {$exists: false}
|
|
273
|
+
}
|
|
244
274
|
|
|
245
275
|
try {
|
|
246
|
-
query =
|
|
247
|
-
_id: (_.isString(id) ? new mongo.ObjectID (id) : id),
|
|
248
|
-
_q: this._name,
|
|
249
|
-
reserved: {$exists: false}
|
|
250
|
-
};
|
|
276
|
+
query._id = (_.isString(id) ? new mongo.ObjectId (id) : id);
|
|
251
277
|
}
|
|
252
278
|
catch (e) {
|
|
253
|
-
return
|
|
279
|
+
return cb ('id [' + id + '] can not be used as remove id: ' + e);
|
|
254
280
|
}
|
|
255
281
|
|
|
256
|
-
this._col.deleteOne (query, {}
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
});
|
|
282
|
+
this._col.deleteOne (query, {})
|
|
283
|
+
.then (res => cb (null, res && (res.deletedCount == 1)))
|
|
284
|
+
.catch (cb);
|
|
260
285
|
}
|
|
261
286
|
|
|
262
287
|
|
package/Queue.js
CHANGED
|
@@ -321,6 +321,8 @@ class Queue {
|
|
|
321
321
|
hdrs: opts.hdrs || {}
|
|
322
322
|
};
|
|
323
323
|
|
|
324
|
+
if (opts.id) msg._id = opts.id;
|
|
325
|
+
|
|
324
326
|
debug ('%s: about to insert %o', this._name, msg);
|
|
325
327
|
|
|
326
328
|
// insert into queue
|
|
@@ -489,9 +491,9 @@ class Queue {
|
|
|
489
491
|
//////////////////////////////////
|
|
490
492
|
// cancel a waiting consumer
|
|
491
493
|
cancel (tid) {
|
|
492
|
-
debug ('%s: cancelling tid %s', this._name, tid);
|
|
493
|
-
|
|
494
494
|
if (tid) {
|
|
495
|
+
debug ('%s: cancelling tid %s', this._name, tid);
|
|
496
|
+
|
|
495
497
|
let consumer_data = this._consumers_by_tid.get (tid);
|
|
496
498
|
|
|
497
499
|
if (!consumer_data) {
|
|
@@ -535,18 +537,27 @@ class Queue {
|
|
|
535
537
|
|
|
536
538
|
debug ('%s: cancelling tid %s (cid %s): callback called and removed', this._name, tid, consumer_data.cid);
|
|
537
539
|
}
|
|
540
|
+
else {
|
|
541
|
+
debug ('%s: cancelling tid %s (cid %s): has no callback!', this._name, tid);
|
|
542
|
+
}
|
|
538
543
|
|
|
539
544
|
if (consumer_data.cleanup_timeout) {
|
|
540
545
|
clearTimeout (consumer_data.cleanup_timeout);
|
|
541
546
|
consumer_data.cleanup_timeout = null;
|
|
542
547
|
debug ('%s: cancelling tid %s (cid %s): cleanup timeout removed', this._name, tid, consumer_data.cid);
|
|
543
548
|
}
|
|
549
|
+
else {
|
|
550
|
+
debug ('%s: cancelling tid %s (cid %s): has no cleanup timeout!', this._name, tid);
|
|
551
|
+
}
|
|
544
552
|
|
|
545
553
|
if (consumer_data.wakeup_timeout) {
|
|
546
554
|
clearTimeout (consumer_data.wakeup_timeout);
|
|
547
555
|
consumer_data.wakeup_timeout = null;
|
|
548
556
|
debug ('%s: cancelling tid %s (cid %s): wakeup timeout removed', this._name, tid, consumer_data.cid);
|
|
549
557
|
}
|
|
558
|
+
else {
|
|
559
|
+
debug ('%s: cancelling tid %s (cid %s): has no wakeup timeout!', this._name, tid);
|
|
560
|
+
}
|
|
550
561
|
|
|
551
562
|
debug ('%s: cancelling tid %s (cid %s): end', this._name, tid, consumer_data.cid);
|
|
552
563
|
});
|
|
@@ -654,9 +665,11 @@ class Queue {
|
|
|
654
665
|
};
|
|
655
666
|
|
|
656
667
|
if (consumer.reserve) {
|
|
668
|
+
debug ('%s - tid %s: calling getOrReserve_cb with reserve', this._name, consumer.tid);
|
|
657
669
|
this.reserve (getOrReserve_cb);
|
|
658
670
|
}
|
|
659
671
|
else {
|
|
672
|
+
debug ('%s - tid %s: calling getOrReserve_cb with get', this._name, consumer.tid);
|
|
660
673
|
this.get (getOrReserve_cb);
|
|
661
674
|
}
|
|
662
675
|
}
|