keuss 1.7.3 → 2.0.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.
Files changed (65) hide show
  1. package/Pipeline/Queue.js +0 -1
  2. package/QFactory.js +11 -6
  3. package/Queue.js +1 -4
  4. package/README.md +2 -1
  5. package/TODO +0 -9
  6. package/backends/bucket-mongo-safe.js +11 -11
  7. package/backends/intraorder.js +13 -11
  8. package/backends/mongo.js +12 -9
  9. package/backends/pl-mongo.js +8 -5
  10. package/backends/postgres.js +380 -0
  11. package/backends/ps-mongo.js +11 -8
  12. package/backends/redis-list.js +8 -8
  13. package/backends/redis-oq.js +8 -3
  14. package/backends/stream-mongo.js +10 -15
  15. package/package.json +14 -10
  16. package/stats/mem.js +0 -1
  17. package/.github/workflows/codeql-analysis.yml +0 -72
  18. package/bench/all-mongo.js +0 -108
  19. package/bench/multi-q.js +0 -85
  20. package/bench/redis-oq-consumer-producer.js +0 -52
  21. package/bench/redis-oq-consumer.js +0 -40
  22. package/bench/redis-oq-producer.js +0 -43
  23. package/docker-compose/docker-compose.yaml +0 -18
  24. package/docker-compose.yaml +0 -18
  25. package/examples/pipelines/builder/index.js +0 -99
  26. package/examples/pipelines/fromRecipe/index.js +0 -127
  27. package/examples/pipelines/simplest/index.js +0 -38
  28. package/examples/pipelines/simulation-fork/index.js +0 -115
  29. package/examples/snippets/01-simplest-pop-push.js +0 -49
  30. package/examples/snippets/02-simplest-reserve-rollback-commit.js +0 -44
  31. package/examples/snippets/03-simplest-producer-consumer-loops.js +0 -77
  32. package/examples/snippets/04-bucket-mongo-safe-insert-reserve-commit.js +0 -78
  33. package/examples/snippets/05-insert-reserve-rollback-deadletter.js +0 -105
  34. package/examples/snippets/06-random-consumer-producer.js +0 -270
  35. package/examples/snippets/07-stream-simple.js +0 -53
  36. package/examples/snippets/redislabs-consumer-producer.js +0 -44
  37. package/examples/snippets/with-redis-stats-and-signaller-consumer-producer.js +0 -52
  38. package/examples/webhooks/README.md +0 -36
  39. package/examples/webhooks/app.js +0 -70
  40. package/examples/webhooks/consumer.js +0 -98
  41. package/examples/webhooks/index.js +0 -55
  42. package/examples/webhooks/package-lock.json +0 -500
  43. package/examples/webhooks/package.json +0 -23
  44. package/examples/webhooks/wh-payload.json +0 -38
  45. package/playground/irc.js +0 -53
  46. package/playground/pl-rollback.js +0 -55
  47. package/playground/pl1.js +0 -74
  48. package/playground/q1.js +0 -34
  49. package/playground/simple-pl.js +0 -42
  50. package/playground/stream-loops.js +0 -114
  51. package/test/backends_bucket-at-least-once.js +0 -302
  52. package/test/backends_deadletter.js +0 -227
  53. package/test/backends_payload.js +0 -542
  54. package/test/backends_push-pop.js +0 -170
  55. package/test/backends_remove.js +0 -320
  56. package/test/backends_reserve-commit-rollback.js +0 -1033
  57. package/test/intraorder.js +0 -325
  58. package/test/pause.js +0 -220
  59. package/test/pipeline-Builder.js +0 -285
  60. package/test/pipeline-ChoiceLink.js +0 -241
  61. package/test/pipeline-DirectLink.js +0 -376
  62. package/test/pipeline-Sink.js +0 -175
  63. package/test/signal.js +0 -196
  64. package/test/stats.js +0 -296
  65. package/test/stream-mongo.js +0 -166
@@ -1,285 +0,0 @@
1
-
2
- var async = require ('async');
3
- var should = require ('should');
4
-
5
- var LocalSignal = require ('../signal/local');
6
- var MemStats = require ('../stats/mem');
7
-
8
-
9
- const MongoClient = require ('mongodb').MongoClient;
10
-
11
- const bs_src_array = [
12
- `
13
- const Chance = require ('chance');
14
- const chance = new Chance();
15
- `,
16
- `
17
- function get_a_delay (min, max) {
18
- return chance.integer ({min, max});
19
- }
20
- `,
21
- `
22
- function sink_process (elem, done) {
23
- setTimeout (() => {
24
- done();
25
-
26
- state.processed++;
27
- if (state.processed == num_elems) {
28
- setTimeout (() => process.exit (0), 1000);
29
- }
30
-
31
- }, get_a_delay (10, 20));
32
- }
33
-
34
- function dl_process (elem, done) {
35
- // pass element to next queue, set payload.passed to true
36
- done (null, {
37
- update: {
38
- $set: {stamp_0: 'passed'}
39
- }
40
- });
41
- }
42
-
43
- function choice_process (elem, done) {
44
- setTimeout (() => {
45
- if (chance.bool ({likelihood: 7})) {
46
- return done ({e: 'cl1 induced a failure'});
47
- }
48
-
49
- const idx = chance.pickone([0, 1, 2]);
50
-
51
- done (null, {
52
- dst: idx,
53
- update: {
54
- $set: {stamp_1: 'passed', choice: idx, choice_try: elem.tries}
55
- }
56
- });
57
- }, get_a_delay (10, 20));
58
- }
59
- `
60
- ];
61
-
62
- const setup_src_array = [
63
- `
64
- const q_opts = {};
65
-
66
- builder
67
- .queue ('test_pl_1', q_opts)
68
- .queue ('test_pl_2', q_opts)
69
- .queue ('test_pl_3', q_opts)
70
- .queue ('test_pl_4', q_opts)
71
- .queue ('test_pl_5', q_opts)
72
- .directLink ('test_pl_1', 'test_pl_2', dl_process)
73
- .choiceLink ('test_pl_2', ['test_pl_3', 'test_pl_4', 'test_pl_5'], choice_process)
74
- .sink ('test_pl_3', sink_process)
75
- .sink ('test_pl_4', sink_process)
76
- .sink ('test_pl_5', sink_process)
77
- .onError ((err) => {})
78
- .done (done);
79
- `
80
- ];
81
-
82
-
83
- function loop (n, fn, cb) {
84
- if (n == 0) return cb ();
85
- fn (n, err => {
86
- if (err) return cb (err);
87
- setImmediate (() => loop (n-1, fn, cb));
88
- });
89
- }
90
-
91
- var factory = null;
92
-
93
- [
94
- {label: 'Pipelined MongoDB', mq: require ('../backends/pl-mongo')}
95
- ].forEach (function (MQ_item) {
96
- describe ('Pipeline/Builder operations over ' + MQ_item.label, function () {
97
- var MQ = MQ_item.mq;
98
-
99
- before (done => {
100
- var opts = {
101
- url: 'mongodb://localhost/__test_pipeline_builder__',
102
- opts: { useUnifiedTopology: true },
103
- signaller: {provider: LocalSignal},
104
- stats: {provider: MemStats}
105
- };
106
-
107
- MQ (opts, (err, fct) => {
108
- if (err) return done (err);
109
- factory = fct;
110
- done();
111
- });
112
- });
113
-
114
- after (done => async.series ([
115
- cb => setTimeout (cb, 1000),
116
- cb => factory.close (cb),
117
- cb => MongoClient.connect ('mongodb://localhost/__test_pipeline_builder__', (err, cl) => {
118
- if (err) return done (err);
119
- cl.db().dropDatabase (() => cl.close (cb))
120
- })
121
- ], done));
122
-
123
-
124
- it ('constructs, runs and destructs a pipeline ok', done => {
125
- let pipeline = null;
126
-
127
- function pl_exit (code) {
128
- pipeline.stop ();
129
- context.state.should.eql ({processed: 7});
130
- done ();
131
- }
132
-
133
- let context = {
134
- state: {
135
- processed: 0
136
- },
137
- num_elems: 7,
138
- process: {
139
- exit: pl_exit
140
- }
141
- };
142
-
143
- factory.pipelineFromRecipe ('__test_pipeline_builder_1__', bs_src_array, setup_src_array, {context: context}, (err, pl) => {
144
- if (err) return done (err);
145
- pipeline = pl;
146
-
147
- pl.start ();
148
-
149
- loop (
150
- context.num_elems,
151
- (n, next) => setTimeout (() => pl.queues()['test_pl_1'].push ({a:n, b:'see it fail...'}, next), 10),
152
- err => {
153
- if (err) done (err);
154
- }
155
- );
156
- });
157
- });
158
-
159
- it ('catches error events in processors', done => {
160
- const bs_src_array_local = [
161
- `
162
- const Chance = require ('chance');
163
- const chance = new Chance();
164
- `,
165
- `
166
- function get_a_delay (min, max) {
167
- return chance.integer ({min, max});
168
- }
169
- `,
170
- `
171
- function sink_process (elem, done) {
172
- setTimeout (() => {
173
- done();
174
-
175
- state.processed++;
176
- if (state.processed == num_elems) {
177
- setTimeout (() => process.exit (0), 1000);
178
- }
179
-
180
- }, get_a_delay (10, 20));
181
- }
182
-
183
- function dl_process (elem, done) {
184
- // pass element to next queue, set payload.passed to true
185
- done (null, {
186
- update: {
187
- $set: {stamp_0: 'passed'}
188
- }
189
- });
190
- }
191
-
192
- function choice_process (elem, done) {
193
- setTimeout (() => {
194
- if (chance.bool ({likelihood: 7})) {
195
- return done ({e: 'cl1 induced a failure'});
196
- }
197
-
198
- const idx = 66;
199
-
200
- done (null, {
201
- dst: idx,
202
- update: {
203
- $set: {stamp_1: 'passed', choice: idx, choice_try: elem.tries}
204
- }
205
- });
206
- }, get_a_delay (10, 20));
207
- }
208
- `
209
- ];
210
-
211
- const setup_src_array_local = [
212
- `
213
- const q_opts = {};
214
-
215
- builder
216
- .queue ('test_pl_1', q_opts)
217
- .queue ('test_pl_2', q_opts)
218
- .queue ('test_pl_3', q_opts)
219
- .queue ('test_pl_4', q_opts)
220
- .queue ('test_pl_5', q_opts)
221
- .directLink ('test_pl_1', 'test_pl_2', dl_process)
222
- .choiceLink ('test_pl_2', ['test_pl_3', 'test_pl_4', 'test_pl_5'], choice_process)
223
- .sink ('test_pl_3', sink_process)
224
- .sink ('test_pl_4', sink_process)
225
- .sink ('test_pl_5', sink_process)
226
- .onError (on_error)
227
- .done (done);
228
- `
229
- ];
230
-
231
- let pipeline;
232
-
233
- function on_error (err) {
234
- err.on.should.equal ('next-queue');
235
- err.err.e.should.equal ('ill-specified dst queue [66]');
236
- err.processor.name().should.equal ('test_pl_2->{test_pl_3,test_pl_4,test_pl_5}');
237
- pipeline.stop ();
238
- done ();
239
- }
240
-
241
- factory.pipelineFromRecipe ('__test_pipeline_builder_2__', bs_src_array_local, setup_src_array_local, {context: {on_error}}, (err, pl) => {
242
- if (err) done (err);
243
- pipeline = pl;
244
- pl.start ();
245
- pl.queues()['test_pl_1'].push ({a:887, b:'see it fail...'}, () => {});
246
- });
247
- });
248
-
249
-
250
- it ('catches errors in js BS scripts on initialization', done => {
251
- const bs_src_array_local = [
252
- 'aaaa()'
253
- ];
254
-
255
- factory.pipelineFromRecipe ('__test_pipeline_builder_2__', bs_src_array_local, setup_src_array, {context: {}}, (err, pl) => {
256
- err.message.should.equal ('aaaa is not defined');
257
- done ();
258
- });
259
- });
260
-
261
-
262
- it ('catches errors in js setup scripts on initialization', done => {
263
- const setup_src_array_local = [
264
- `
265
- const q_opts = {};
266
-
267
- builder
268
- .queue ('test_pl_1', q_opts)
269
- .queue ('test_pl_2', q_opts)
270
- .directLink ('test_pl_1', 'test_pl_3', dl_process)
271
- .onError ((err) => {})
272
- .done (done);
273
- `
274
- ];
275
-
276
- factory.pipelineFromRecipe ('__test_pipeline_builder_3__', bs_src_array, setup_src_array_local, {context: {}}, (err, pl) => {
277
- err.should.equal ('when creating DirectLink: nonexistent dst queue [test_pl_3]')
278
- done ();
279
- });
280
- });
281
-
282
- it ('propagates to a second pipeline instance');
283
-
284
- });
285
- });
@@ -1,241 +0,0 @@
1
- const async = require ('async');
2
- const should = require ('should');
3
- const Chance = require ('chance');
4
-
5
- var LocalSignal = require ('../signal/local');
6
- var MemStats = require ('../stats/mem');
7
-
8
- const MongoClient = require('mongodb').MongoClient;
9
-
10
- const CHC = require ('../Pipeline/ChoiceLink');
11
- const SNK = require ('../Pipeline/Sink');
12
-
13
- const chance = new Chance();
14
- var factory = null;
15
-
16
-
17
- function loop (n, fn, cb) {
18
- if (n == 0) return cb ();
19
- fn (n, err => {
20
- if (err) return cb (err);
21
- setImmediate (() => loop (n-1, fn, cb));
22
- });
23
- }
24
-
25
- [
26
- {label: 'Pipelined MongoDB', mq: require ('../backends/pl-mongo')}
27
- ].forEach (function (MQ_item) {
28
- describe ('Pipeline/ChoiceLink operations over ' + MQ_item.label, function () {
29
- const MQ = MQ_item.mq;
30
-
31
- before (done => {
32
- const opts = {
33
- url: 'mongodb://localhost/__test_pipeline_choicelink__',
34
- opts: { useUnifiedTopology: true },
35
- signaller: { provider: LocalSignal},
36
- stats: {provider: MemStats}
37
- };
38
-
39
- MQ (opts, (err, fct) => {
40
- if (err) return done (err);
41
- factory = fct;
42
- done();
43
- });
44
- });
45
-
46
- after (done => async.series ([
47
- cb => setTimeout (cb, 1000),
48
- cb => factory.close (cb),
49
- cb => MongoClient.connect ('mongodb://localhost/__test_pipeline_choicelink__', (err, cl) => {
50
- if (err) return done (err);
51
- cl.db().dropDatabase (() => cl.close (cb))
52
- })
53
- ], done));
54
-
55
- it ('3-elem choice pipeline distributes ok', done => {
56
- const score = {
57
- total: 17,
58
- next_idx: 0,
59
- received: {
60
- total: 0
61
- }
62
- };
63
-
64
- const q_opts = {pipeline: 'pl1'};
65
-
66
- const q1 = factory.queue ('pl_many_q_1', q_opts);
67
- const q2 = factory.queue ('pl_many_q_2', q_opts);
68
- const q3 = factory.queue ('pl_many_q_3', q_opts);
69
- const q4 = factory.queue ('pl_many_q_4', q_opts);
70
-
71
- // tie them up:
72
- const cl1 = new CHC (q1, [q2, q3, q4]);
73
- const sk1 = new SNK (q2);
74
- const sk2 = new SNK (q3);
75
- const sk3 = new SNK (q4);
76
-
77
- cl1.dst_dimension().should.equal(3);
78
- cl1.dst_names().should.eql (['pl_many_q_2', 'pl_many_q_3', 'pl_many_q_4']);
79
-
80
- function sink_process (elem, done0) {
81
- score.received.total++;
82
- if (!score.received[this.name()]) score.received[this.name()] = [];
83
- score.received[this.name()].push (elem.payload.a);
84
-
85
- if (score.received.total == score.total) {
86
- setTimeout (() => {
87
- score.should.eql ({
88
- total: 17,
89
- next_idx: 2,
90
- received: {
91
- total: 17,
92
- 'pl_many_q_2->(sink)': [ 17, 14, 11, 8, 5, 2 ],
93
- 'pl_many_q_3->(sink)': [ 16, 13, 10, 7, 4, 1 ],
94
- 'pl_many_q_4->(sink)': [ 15, 12, 9, 6, 3 ]
95
- }
96
- });
97
-
98
- setTimeout (done, 250);
99
- }, 100);
100
- }
101
-
102
- done0();
103
- }
104
-
105
- sk1.start (sink_process);
106
- sk2.start (sink_process);
107
- sk3.start (sink_process);
108
-
109
- cl1.start (function (elem, done) {
110
- const idx = score.next_idx++;
111
- if (score.next_idx > 2) score.next_idx = 0;
112
-
113
- done (null, {
114
- dst: idx,
115
- update: {
116
- $set: {stamp: 'passed', choice: idx}
117
- }
118
- });
119
- });
120
-
121
- loop (
122
- score.total,
123
- (n, next) => setTimeout (() => q1.push ({a:n, b:'see it fail...'}, next), chance.integer ({min:50, max: 100})),
124
- err => {
125
- if (err) done (err);
126
- }
127
- );
128
- });
129
-
130
-
131
- it ('manages non-index correctly', done => {
132
- const q_opts = {pipeline: 'pl2'};
133
-
134
- const q1 = factory.queue ('pl_many_q_1', q_opts);
135
- const q2 = factory.queue ('pl_many_q_2', q_opts);
136
- const q3 = factory.queue ('pl_many_q_3', q_opts);
137
- const q4 = factory.queue ('pl_many_q_4', q_opts);
138
-
139
- // tie them up:
140
- const cl1 = new CHC (q1, [q2, q3, q4]);
141
- const sk1 = new SNK (q2);
142
- const sk2 = new SNK (q3);
143
- const sk3 = new SNK (q4);
144
-
145
- function sink_process (elem, done0) {
146
- done0();
147
- }
148
-
149
- sk1.start (sink_process);
150
- sk2.start (sink_process);
151
- sk3.start (sink_process);
152
-
153
- cl1.on ('error', err => {
154
- err.should.match ({
155
- on: 'next-queue',
156
- elem: {
157
- payload: { a: 666, b: 'see it fail...' },
158
- tries: 0,
159
- _q: 'pl_many_q_1'
160
- },
161
- opts: { dst: 6 },
162
- err: { e: 'ill-specified dst queue [6]' }
163
- });
164
-
165
- sk1.stop ();
166
- sk2.stop ();
167
- sk3.stop ();
168
-
169
- setTimeout (() => {
170
- const client = new MongoClient('mongodb://localhost/__test_pipeline_choicelink__');
171
- client.connect(err => {
172
- client.db().collection ('pl2').deleteMany ({}, () => done ());
173
- });
174
- }, 250);
175
- });
176
-
177
- cl1.start (function (elem, done) {
178
- done (null, {dst: 6});
179
- });
180
-
181
- q1.push ({a:666, b:'see it fail...'}, () => {});
182
- });
183
-
184
-
185
-
186
- it ('manages non-name correctly', done => {
187
- const q_opts = {pipeline: 'pl3'};
188
-
189
- const q1 = factory.queue ('pl_many_q_1', q_opts);
190
- const q2 = factory.queue ('pl_many_q_2', q_opts);
191
- const q3 = factory.queue ('pl_many_q_3', q_opts);
192
- const q4 = factory.queue ('pl_many_q_4', q_opts);
193
-
194
- // tie them up:
195
- const cl1 = new CHC (q1, [q2, q3, q4]);
196
- const sk1 = new SNK (q2);
197
- const sk2 = new SNK (q3);
198
- const sk3 = new SNK (q4);
199
-
200
- function sink_process (elem, done0) {
201
- done0();
202
- }
203
-
204
- sk1.start (sink_process);
205
- sk2.start (sink_process);
206
- sk3.start (sink_process);
207
-
208
- cl1.on ('error', err => {
209
- err.should.match ({
210
- on: 'next-queue',
211
- elem: {
212
- payload: { a: 666, b: 'see it fail...' },
213
- tries: 0,
214
- _q: 'pl_many_q_1'
215
- },
216
- opts: { dst: 'nowhere' },
217
- err: { e: 'ill-specified dst queue [nowhere]' }
218
- });
219
-
220
- sk1.stop ();
221
- sk2.stop ();
222
- sk3.stop ();
223
-
224
- setTimeout (() => {
225
- const client = new MongoClient('mongodb://localhost/__test_pipeline_choicelink__');
226
- client.connect(err => {
227
- client.db().collection ('pl3').deleteMany ({}, () => done ());
228
- });
229
- }, 250);
230
- });
231
-
232
- cl1.start (function (elem, done) {
233
- done (null, {dst: 'nowhere'});
234
- });
235
-
236
- q1.push ({a:666, b:'see it fail...'}, () => {});
237
- });
238
-
239
-
240
- });
241
- });