keuss 1.7.4 → 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 +12 -8
  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,105 +0,0 @@
1
- /*
2
- *
3
- * deadletter simple demo: an item is repeatedly reserved and rejected, and
4
- * after some rejections, the element goes to the __deadletter__ instead of
5
- * going back to its queue (which is caught at the pop at line 98)
6
- *
7
- */
8
-
9
- // var MQ = require('../../backends/bucket-mongo-safe');
10
- // var MQ = require('../../backends/redis-oq');
11
- var MQ = require('../../backends/ps-mongo');
12
-
13
- var async = require('async');
14
-
15
-
16
- function stats (q, cb) {
17
- q.stats((err, res) => {
18
- console.log('queue stats now: %o', res);
19
- cb(err);
20
- });
21
- }
22
-
23
- function pop (q, stage, cb) {
24
- q.pop('c1', { reserve: true }, (err, res) => {
25
- stage.obj = res;
26
- console.log('reserved element %o', res);
27
- cb(err);
28
- });
29
- }
30
-
31
- function reject (q, stage, cb) {
32
- var next_t = new Date().getTime() + 2000;
33
-
34
- q.ko (stage.obj, next_t, (err, res) => {
35
- if (err) {
36
- console.error ('error in rollback of %s: %o', stage.obj._id, err);
37
- return cb (err);
38
- }
39
-
40
- console.log('rolled back element %s: %o', stage.obj._id, res);
41
- cb();
42
- });
43
- }
44
-
45
- function accept (q, stage, cb) {
46
- q.ok (stage.obj, (err, res) => {
47
- if (err) {
48
- console.error ('error in rollback of %s: %o', stage.obj._id, err);
49
- return cb (err);
50
- }
51
-
52
- console.log('commited element %s: %o', stage.obj._id, res);
53
- cb();
54
- });
55
- }
56
-
57
-
58
- var factory_opts = {
59
- url: 'mongodb://localhost/qeus',
60
- deadletter: {
61
- max_ko: 3
62
- }
63
- };
64
-
65
- // initialize factory
66
- MQ(factory_opts, (err, factory) => {
67
- if (err) return console.error(err);
68
-
69
- // factory ready, create one queue
70
- var q = factory.queue('test_queue_rcr', {});
71
-
72
- // state is kept here
73
- var stage = {};
74
-
75
- async.series([
76
- cb => q.push({ elem: 1, pl: 'twetrwte' }, (err, res) => {
77
- console.log('pushed element');
78
- cb(err);
79
- }),
80
- cb => pop (q, stage, cb),
81
- cb => reject (q, stage, cb),
82
- cb => pop (q, stage, cb),
83
- cb => reject (q, stage, cb),
84
- cb => pop (q, stage, cb),
85
- cb => reject (q, stage, cb),
86
- cb => pop (q, stage, cb),
87
- cb => reject (q, stage, cb),
88
- cb => pop (q, stage, cb),
89
- cb => reject (q, stage, cb),
90
- cb => pop (q, stage, cb),
91
- cb => reject (q, stage, cb)
92
- ], err => {
93
- // all done
94
- if (err) console.error ('reject_line error: ', err);
95
- else console.log ('reject_line done');
96
- });
97
-
98
- factory.deadletter_queue().pop('c2', (err, res) => {
99
- console.log('from deadletter_queue, got element %o', res);
100
- setTimeout (() => {
101
- q.cancel ();
102
- factory.close (() => console.log ('done'));
103
- }, 1000);
104
- });
105
- });
@@ -1,270 +0,0 @@
1
- /*
2
- *
3
- * Runs a set of producers and consumers, where consumers do a reserve-commit-rollback cycle. In each cycle a
4
- * consumer would randomly choose whether to commit or rollback (10% chance of rollback). No deadletter is used
5
- * so elements are retried ad infinitum until processed ok
6
- *
7
- * Upon completion (all items generated and consumed ok) some stats will be shown
8
- *
9
- * It uses bucket-mongo-safe backend for high throughput
10
- *
11
- */
12
-
13
- var MQ = require ('../../backends/bucket-mongo-safe');
14
-
15
- var _ = require ('lodash');
16
- var async = require ('async');
17
- var Chance = require ('chance');
18
- var chance = new Chance();
19
-
20
-
21
- var factory_opts = {
22
- url: 'mongodb://localhost/qeus',
23
- name: 'Random-NS',
24
- reject_delta_base: 2000,
25
- reject_delta_factor: 2000
26
- };
27
-
28
- // test dimensions: elems to produce and consume, number of consumers, number of producers
29
- const num_elems = 1000000;
30
- const num_producers = 3;
31
- const num_consumers = 7;
32
- const commit_likelihood = 75;
33
-
34
- // stats holder
35
- var selfs = {
36
- consumers: {},
37
- producers: {}
38
- };
39
-
40
- var shareds = {};
41
-
42
-
43
- //////////////////////////////////////////////////////////////////////////////////////////////////////////////
44
- function consume_one (shared_ctx, self_ctx, cb) {
45
- if (shared_ctx.pop_count > shared_ctx.pop_max) {
46
- console.log ('pop consumer %s ended', self_ctx.id);
47
- shared_ctx.q.cancel ();
48
- return cb ();
49
- }
50
-
51
- shared_ctx.pop_count ++;
52
- self_ctx.pop_count ++;
53
-
54
- shared_ctx.q.pop (self_ctx.id, shared_ctx.pop_opts, (err, res) => {
55
- if (err) return cb (err);
56
- if ((shared_ctx.pop_count % 100000) == 0) console.log ('%s : consumed #%d elems', self_ctx.id, shared_ctx.pop_count);
57
- consume_one (shared_ctx, self_ctx, cb);
58
- });
59
- }
60
-
61
-
62
- function run_a_pop_consumer (shared_ctx, cb) {
63
- var self_ctx = {
64
- id: chance.word (),
65
- pop_count: 0
66
- };
67
-
68
- selfs.consumers[self_ctx.id] = self_ctx;
69
-
70
- consume_one (shared_ctx, self_ctx, cb);
71
- }
72
-
73
-
74
- function run_consumers (q, cnt, cb) {
75
- var shared_ctx = {
76
- q: q,
77
- pop_count: 0,
78
- pop_max: cnt,
79
- pop_opts: {}
80
- };
81
-
82
- shareds.pc = shared_ctx;
83
-
84
- var tasks = [];
85
- for (var i = 0; i < num_consumers; i++) tasks.push ((cb) => run_a_pop_consumer (shared_ctx, cb));
86
- async.parallel (tasks, cb);
87
- }
88
-
89
- //////////////////////////////////////////////////////////////////////////////////////////////////////////////
90
-
91
- var das_pop = 0;
92
- var das_ko = 0;
93
- var das_ok = 0;
94
-
95
- //////////////////////////////////////////////////////////////////////////////////////////////////////////////
96
- function reserve_and_commit_one (shared_ctx, self_ctx, cb) {
97
- self_ctx.pop_count ++;
98
-
99
- shared_ctx.q.pop (self_ctx.consumer, shared_ctx.pop_opts, (err, res) => {
100
- if (err) return cb (err);
101
- self_ctx.resv_count ++;
102
-
103
- das_pop++;
104
-
105
- if (chance.bool({likelihood: commit_likelihood})) {
106
- shared_ctx.q.ok (res._id, (err) => {
107
- if (err) return cb (err);
108
- self_ctx.ok_count ++;
109
- shared_ctx.pop_count ++;
110
- das_ok++;
111
-
112
- if (shared_ctx.pop_count > shared_ctx.pop_max) {
113
- console.log ('rcr consumer %s ended', self_ctx.id);
114
- shared_ctx.q.cancel ();
115
- return cb ();
116
- }
117
-
118
- // if ((shared_ctx.pop_count % 100000) == 0) console.log ('%s : consumed #%d elems', self_ctx.id, shared_ctx.pop_count);
119
- reserve_and_commit_one (shared_ctx, self_ctx, cb);
120
- });
121
- }
122
- else {
123
- shared_ctx.q.ko (res._id, (err) => {
124
- if (err) return cb (err);
125
- self_ctx.ko_count ++;
126
- das_ko++;
127
-
128
- // if ((shared_ctx.pop_count % 100000) == 0) console.log ('%s : consumed #%d elems', self_ctx.id, shared_ctx.pop_count);
129
- reserve_and_commit_one (shared_ctx, self_ctx, cb);
130
- });
131
- }
132
- });
133
- }
134
-
135
- function run_a_rcr_consumer (shared_ctx, cb) {
136
- var self_ctx = {
137
- id: chance.word (),
138
- pop_count: 0,
139
- resv_count: 0,
140
- ko_count: 0,
141
- ok_count: 0
142
- };
143
-
144
- selfs.consumers[self_ctx.id] = self_ctx;
145
-
146
- reserve_and_commit_one (shared_ctx, self_ctx, cb);
147
- }
148
-
149
- function run_rcr_consumers (q, cnt, cb) {
150
- var shared_ctx = {
151
- q: q,
152
- pop_count: 0,
153
- pop_max: cnt,
154
- pop_opts: {
155
- reserve: true
156
- }
157
- };
158
-
159
- shareds.rcrc = shared_ctx;
160
-
161
- var tasks = [];
162
- for (var i = 0; i < num_consumers; i++)
163
- tasks.push ((cb) => run_a_rcr_consumer (shared_ctx, cb));
164
-
165
- async.parallel (tasks, cb);
166
- }
167
-
168
- //////////////////////////////////////////////////////////////////////////////////////////////////////////////
169
-
170
-
171
-
172
- //////////////////////////////////////////////////////////////////////////////////////////////////////////////
173
- function produce_one (shared_ctx, self_ctx, cb) {
174
- if (shared_ctx.push_count > shared_ctx.push_max) {
175
- console.log ('producer %s ended', self_ctx.id);
176
- return cb ();
177
- }
178
-
179
- shared_ctx.push_count ++;
180
- self_ctx.push_count ++;
181
-
182
- shared_ctx.q.push ({a: chance.integer (), b: chance.word (), n: shared_ctx.push_count}, function (err, res) {
183
- if (err) return console.error (err);
184
- // if ((shared_ctx.push_count % 100000) == 0) console.log ('%s : produced #%d elems', self_ctx.id, shared_ctx.push_count);
185
- produce_one (shared_ctx, self_ctx, cb);
186
- });
187
- }
188
-
189
- function run_a_producer (shared_ctx, cb) {
190
- var self_ctx = {
191
- id: chance.word (),
192
- push_count: 0
193
- };
194
-
195
- selfs.producers[self_ctx.id] = self_ctx;
196
-
197
- produce_one (shared_ctx, self_ctx, cb);
198
- }
199
-
200
- function run_producers (q, cnt, cb) {
201
- var shared_ctx = {
202
- q: q,
203
- push_count: 0,
204
- push_max: cnt
205
- };
206
-
207
- shareds.prod = shared_ctx;
208
-
209
- var tasks = [];
210
- for (var i = 0; i < num_producers; i++) tasks.push ((cb) => run_a_producer (shared_ctx, cb));
211
- async.parallel (tasks, cb);
212
- }
213
-
214
- //////////////////////////////////////////////////////////////////////////////////////////////////////////////
215
-
216
-
217
- // initialize factory
218
- MQ (factory_opts, function (err, factory) {
219
- if (err) return console.error (err);
220
-
221
- // factory ready, create one queue
222
- var q_opts = {};
223
- var q = factory.queue ('test_queue_456', q_opts);
224
-
225
- var timer = setInterval (() => {
226
- console.log ('**** state: %o', _.map (shareds, (v, k) => {return {cnt: v.push_count || v.pop_count, max: v.push_max || v.pop_max }}));
227
-
228
- console.log ('das pop %d, ko %d, ok %d', das_pop, das_ko, das_ok);
229
-
230
- q.status ((err ,res) => {
231
- console.log ('**** status: %o', res);
232
- });
233
- }, 2000);
234
-
235
- async.parallel ([
236
- (cb) => run_producers (q, num_elems, cb),
237
- // (cb) => run_consumers (q, 250000, cb),
238
- (cb) => run_rcr_consumers (q, num_elems, cb),
239
- ], (err) => {
240
- if (err) {
241
- console.error (err);
242
- }
243
-
244
- var tot_push = 0;
245
- var tot_pop = 0;
246
- var tot_resv = 0;
247
- var tot_ok = 0;
248
- var tot_ko = 0;
249
-
250
- console.log ('\nProducers: ');
251
- _.each (selfs.producers, (v, k) => {console.log (' %s: pushed %d', v.id, v.push_count), tot_push += v.push_count});
252
-
253
- console.log ('\nConsumers: ');
254
- _.each (selfs.consumers, (v, k) => {
255
- console.log (' %s: popped %d, resvd %d, committed %d, rollbacked %d', v.id, v.pop_count, v.resv_count, v.ok_count, v.ko_count);
256
- tot_pop += v.pop_count;
257
- tot_resv += v.resv_count;
258
- tot_ok += v.ok_count;
259
- tot_ko += v.ko_count;
260
- });
261
-
262
- console.log (' \nTotals: %d popped, %d pushed, resvd %d, committed %d, rollbacked %d', tot_pop, tot_push, tot_resv, tot_ok, tot_ko);
263
- clearInterval (timer);
264
-
265
- q.status ((err ,res) => {
266
- console.log ('**** status: %o', res);
267
- q.drain (() => factory.close ());
268
- });
269
- });
270
- });
@@ -1,53 +0,0 @@
1
- /*
2
- *
3
- * very simple example of stream-mongo: one element pushed, consumed three times
4
- *
5
- */
6
-
7
- const async = require ('async');
8
- const MQ = require ('../../backends/stream-mongo');
9
-
10
- // initialize factory
11
- MQ ({
12
- url: 'mongodb://localhost/keuss_test_stream'
13
- }, (err, factory) => {
14
- if (err) return console.error(err);
15
-
16
- // factory ready, create one queue
17
- const q0 = factory.queue ('test_stream', {groups: 'G1, G2, G4'});
18
- const q1 = factory.queue ('test_stream', {group: 'G1'});
19
- const q2 = factory.queue ('test_stream', {group: 'G2'});
20
-
21
- async.series ([
22
- // push element
23
- cb => q0.push (
24
- {elem: 1, headline: 'something something', tags: {a: 1, b: 2}}, // this is the payload
25
- {
26
- hdrs: {h1: 'aaa', h2: 12, h3: false} // let's add some headers too
27
- },
28
- cb
29
- ),
30
- cb => setTimeout (cb, 1000), // wait a bit
31
- cb => q1.pop ('consumer-1', cb), // pop element in group G1
32
- cb => q2.pop ('consumer-2', cb), // pop element in group G2
33
- ], (err, res) => {
34
- if (err) {
35
- console.error (err);
36
- }
37
- else {
38
- console.log ('element popped for group G1:', res[2]);
39
- console.log ('element popped for group G2:', res[3]);
40
- // this should print twice something like:
41
- // {
42
- // _id: <some id>,
43
- // mature: <some date>,
44
- // payload: { elem: 1, headline: 'something something', tags: { a: 1, b: 2 } },
45
- // tries: 0
46
- // hdrs: {h1: 'aaa', h2: 12, h3: false}
47
- // }
48
- }
49
-
50
- factory.close ();
51
- });
52
- });
53
-
@@ -1,44 +0,0 @@
1
- // redis-list consumer & producer on a redislabs Redis
2
-
3
- var MQ = require('../../backends/redis-list');
4
-
5
- var factory_opts = {
6
- redis: {
7
- Redis: {
8
- port: 12345,
9
- host: 'redis-12345.c3.eu-west-1-2.ec2.cloud.redislabs.com',
10
- family: 4,
11
- password: 'xxxxxxxx',
12
- db: 0
13
- }
14
- }
15
- };
16
-
17
- // initialize factory
18
- MQ(factory_opts, function (err, factory) {
19
- if (err) {
20
- return console.error(err);
21
- }
22
-
23
- // factory ready, create one queue
24
- var q_opts = {};
25
- var q = factory.queue('test_queue', q_opts);
26
-
27
- // insert element
28
- q.push({ a: 1, b: '666' }, function (err, res) {
29
- if (err) {
30
- return console.error(err);
31
- }
32
-
33
- // element inserted at this point. pop it again
34
- var pop_opts = {};
35
- q.pop('consumer-one', pop_opts, function (err, res) {
36
- if (err) {
37
- return console.error(err);
38
- }
39
-
40
- console.log('got this: ', res.payload);
41
- });
42
- });
43
-
44
- });
@@ -1,52 +0,0 @@
1
- // mongodb: create a consumer and a producer, use redis signaller and redis stats
2
- var MQ = require ('../backends/mongo');
3
- var signal_redis_pubsub = require ('../signal/redis-pubsub');
4
- var stats_redis = require ('../stats/redis');
5
-
6
- var local_redis_opts = {
7
- Redis: {
8
- port: 6379,
9
- host: 'localhost',
10
- db: 6
11
- }
12
- };
13
-
14
- var factory_opts = {
15
- url: 'mongodb://localhost/qeus',
16
- signaller: {
17
- provider: signal_redis_pubsub,
18
- opts: local_redis_opts
19
- },
20
- stats: {
21
- provider: stats_redis,
22
- opts: local_redis_opts
23
- }
24
- };
25
-
26
- // initialize factory
27
- MQ (factory_opts, function (err, factory) {
28
- if (err) {
29
- return console.error (err);
30
- }
31
-
32
- // factory ready, create one queue
33
- var q_opts = {};
34
- var q = factory.queue ('test_queue_123', q_opts);
35
-
36
- // insert element
37
- q.push ({a:1, b:'666'}, function (err, res) {
38
- if (err) {
39
- return console.error (err);
40
- }
41
-
42
- // element inserted at this point. pop it again
43
- var pop_opts = {};
44
- q.pop ('consumer-one', pop_opts, function (err, res) {
45
- if (err) {
46
- return console.error (err);
47
- }
48
-
49
- console.log ('got this: ', res.payload);
50
- });
51
- });
52
- });
@@ -1,36 +0,0 @@
1
- # Keuss example app: WebHook delivery
2
-
3
- This is a small but fully functional WebHook Delivery System using keuss as job-queue middleware. It can be certainly improved in many ways, but it is perfectly usable in its current state
4
-
5
- ## install & run
6
- You need a mongodb instance running locally.
7
-
8
- Then, run the usual `npm install` and then `node .`
9
-
10
- ## How it works
11
- This system works as a store-and-forward http relay:
12
- * you make HTTP calls (any method) to `http://localhost:6677/wh`. The whole HTTP request will be queued for later. You'll receive a `HTTP 201 Created` response, immediately
13
- * The queued requests are extracted by means of a reserve from the queue and *executed*.
14
- * If they fail with a retriable error (http 5xx, non-http errors) they are rolled back with a delay of `tries^2 * 3 + tries * 3 + 3` seconds.
15
- * If they fail with a non-retriable error (http 4xx) they are committed
16
- * If they succeed (http 2xx) they are committed
17
- * Also, deadletter is used. If a webhook is retried over 14 times, it is moved to `__deadletter__`
18
-
19
- In order to work, you need to pass along the destination url as `x-dest-url` header. This header is not passed along. Also, you can specify an initial delay in secons in the header `x-delay`, which is not passed along either
20
-
21
- A set of testing urls is also provided for a self-contained testing:
22
- * `/test/200`: returns a HTTP 200
23
- * `/test/400`: returns a HTTP 400
24
- * `/test/404`: returns a HTTP 404
25
- * `/test/500`: returns a HTTP 500
26
- * `/test/drop`: no response, and close the socket
27
-
28
- Then, you can issue a POST webhook which would be retried 14 times and then moved to deadletter like this:
29
-
30
- ```bash
31
- curl -X POST --data-bin @wh-payload.json -v -H 'x-dest-url: http://localhost:6677/test/500' -H 'content-type: text/plain' -H 'x-delay: 1' http://localhost:6677/wh
32
- ```
33
-
34
- You would need to first create a file `wh-payload.json` with the webhook payload or content. Also, it will be issued with an initial delay of 1 second.
35
- The provided sample in the `wh-payload.json` file is a sample content for posting a message to a Microsoft Teams channel using webhooks connector. You can find the sample and more concrete explanation of how to build your own cards for Microsoft Teams here:
36
- https://docs.microsoft.com/en-us/microsoftteams/platform/task-modules-and-cards/cards/cards-reference#thumbnail-card
@@ -1,70 +0,0 @@
1
- const express = require ('express');
2
- const bodyParser = require ('body-parser');
3
-
4
-
5
- module.exports = (context) => {
6
- var app = express();
7
-
8
- // parse everything as text. A more robust and generic solution shoudl use raw() and manage Buffers, though
9
- app.use (bodyParser.text ({type: () => true}));
10
-
11
- // main server entry point: anything here is queued for async delivery
12
- app.all ('/wh', (req, res) => {
13
- const url = req.headers['x-dest-url'];
14
- let delay = 0;
15
-
16
- // we expect a header x-dest-url to specif the webhook's url
17
- if (!url) return res.status (400).send ('no x-dest-url, ignoring request');
18
-
19
- // one can specify the initial delay, if desired
20
- const delay_str = req.headers['x-delay'];
21
- if (delay_str) {
22
- delete req.headers['x-delay'];
23
- delay = parseInt (delay_str);
24
- }
25
-
26
- // build the payload...
27
- delete req.headers['x-dest-url'];
28
- const pl = {
29
- url: url,
30
- method: req.method,
31
- headers: req.headers,
32
- body: req.body
33
- };
34
-
35
- // ...and queue it
36
- context.q.push (pl, {delay: delay}, (err, id) => {
37
- // error while queuing?
38
- if (err) {
39
- console.error ('error whipe pushing payload:', err);
40
- return res.status (500).send (err);
41
- }
42
-
43
- // no errors, return a 201 Created...
44
- console.log ('inserted element with id %s', id);
45
- return res.status (201).send ({res: 'ok', id: id});
46
- });
47
- });
48
-
49
-
50
- // test respnses for various http response codes
51
- app.all ('/test/200', (req, res) => res.status (200).send ('a 200'));
52
- app.all ('/test/400', (req, res) => res.status (400).send ('a 400'));
53
- app.all ('/test/404', (req, res) => res.status (404).send ('a 404'));
54
- app.all ('/test/500', (req, res) => res.status (500).send ('a 500'));
55
-
56
- // do not respond
57
- app.all ('/test/noresponse', (req, res) => {});
58
-
59
- // close socket
60
- app.all ('/test/drop', (req, res) => req.socket.destroy());
61
-
62
- // express error manager
63
- app.use (function (err, req, res, next) {
64
- console.error ('error caught: %s', err.stack);
65
- res.status (err.status || 500).send (err.stack);
66
- });
67
-
68
- return app;
69
- };
70
-