@tiledesk/tiledesk-server 2.5.3 → 2.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,355 @@
1
+ var amqp = require('amqplib/callback_api');
2
+
3
+ var listeners = [];
4
+
5
+
6
+ class QueueManager {
7
+
8
+ constructor(url, options) {
9
+ this.debug = false;
10
+ if (options && options.debug!=undefined) {
11
+ this.debug = options.debug;
12
+ }
13
+
14
+ this.pubChannel = null;
15
+ this.offlinePubQueue = [];
16
+
17
+ // if the connection is closed or fails to be established at all, we will reconnect
18
+ this.amqpConn = null;
19
+
20
+ this.url = url || "amqp://localhost";
21
+ // process.env.CLOUDAMQP_URL + "?heartbeat=60"
22
+
23
+ // this.exchange = 'amq.topic';
24
+ this.exchange = 'tiledeskserver';
25
+ if (options && options.exchange!=undefined) {
26
+ this.exchange = options.exchange;
27
+ }
28
+ this.defaultTopic = "subscription_run";
29
+ if (options && options.defaultTopic!=undefined) {
30
+ this.defaultTopic = options.defaultTopic;
31
+ }
32
+
33
+ this.topic = "jobsmanager";
34
+ if (options && options.topic!=undefined) {
35
+ this.topic = options.topic;
36
+ }
37
+
38
+ // this.listeners = [];
39
+ }
40
+
41
+
42
+ connect(callback) {
43
+ var that = this;
44
+ // console.log("[JobWorker] connect", this.url);
45
+ // return new Promise(function (resolve, reject) {
46
+ amqp.connect(this.url, function(err, conn) {
47
+ if (err) {
48
+ // if (this.debug) {console.log("[AMQP]", err.message);
49
+ if (that.debug) {console.log("[JobWorker] AMQP", err);}
50
+
51
+ return setTimeout(function() {
52
+ that.connect()
53
+ }, 1000);
54
+ }
55
+ conn.on("error", function(err) {
56
+ if (err.message !== "Connection closing") {
57
+ if (that.debug) {console.log("[JobWorker] AMQP conn error", err);}
58
+ }
59
+ });
60
+ conn.on("close", function() {
61
+ if (that.debug) {console.log("[JobWorker] AMQP reconnecting");}
62
+ return setTimeout(that.connect, 1000);
63
+ });
64
+
65
+ if (that.debug) {console.log("[JobWorker] AMQP connected");}
66
+ that.amqpConn = conn;
67
+
68
+ // that.whenConnected(callback);
69
+
70
+ if (callback) {
71
+ callback();
72
+ }
73
+ // return resolve();
74
+ // });
75
+ });
76
+ }
77
+
78
+ close(callback) {
79
+ if (this.debug) { console.log("Closing connection.."); };
80
+ this.amqpConn.close((err) => {
81
+ callback(err);
82
+ });
83
+
84
+ }
85
+
86
+ whenConnected(callback) {
87
+ var that = this;
88
+ // that.startPublisher(callback);
89
+ that.startPublisher();
90
+ that.startWorker(callback);
91
+ }
92
+
93
+
94
+ startPublisher(callback) {
95
+ var that = this;
96
+ that.amqpConn.createConfirmChannel(function(err, ch) {
97
+ if (that.closeOnErr(err)) return;
98
+ ch.on("error", function(err) {
99
+ if (that.debug) {console.log("[JobWorker] AMQP channel error", err);}
100
+ });
101
+ ch.on("close", function() {
102
+ if (that.debug) {console.log("[JobWorker] AMQP channel closed");}
103
+ });
104
+
105
+ // if (this.debug) {console.log("[AMQP] pubChannel");
106
+ that.pubChannel = ch;
107
+ // console.log("[JobWorker] that.pubChannel",that.pubChannel);
108
+ // while (true) {
109
+ // var m = that.offlinePubQueue.shift();
110
+ // if (!m) break;
111
+ // that.publish(m[0], m[1], m[2]);
112
+ // }
113
+
114
+ if (callback) {
115
+ callback(err);
116
+ }
117
+
118
+ });
119
+ }
120
+
121
+ // method to publish a message, will queue messages internally if the connection is down and resend later
122
+ publish(exchange, routingKey, content, callback) {
123
+ var that = this;
124
+ if (that.debug) {console.log("[JobWorker] that", that);}
125
+ if (that.debug) {console.log("[JobWorker] that.pubChannel", that.pubChannel);}
126
+ that.pubChannel.publish(exchange, routingKey, content, { persistent: false },
127
+ function(err, ok) {
128
+ callback(err, ok)
129
+ }
130
+ );
131
+
132
+ // try {
133
+ // if (that.debug) {console.log("[JobWorker] that", that);}
134
+ // if (that.debug) {console.log("[JobWorker] that.pubChannel", that.pubChannel);}
135
+ // that.pubChannel.publish(exchange, routingKey, content, { persistent: false },
136
+ // function(err, ok) {
137
+ // callback(err, ok)
138
+ // // if (err) {
139
+ // // // if (that.debug) {console.log("[JobWorker] AMQP publish", err);}
140
+ // // // console.log("[JobWorker] AMQP publish", err);
141
+ // // // that.offlinePubQueue.push([exchange, routingKey, content]);
142
+ // // // that.pubChannel.connection.close();
143
+ // // }
144
+ // // console.log("publish OK")
145
+ // // // if (that.debug) {console.log("[AMQP] publish sent", content);}
146
+ // });
147
+ // } catch (e) {
148
+ // console.log("[JobWorker] AMQP publish catch", e);
149
+ // if (this.debug) {console.log("[JobWorker] AMQP publish", e);}
150
+ // that.offlinePubQueue.push([exchange, routingKey, content]);
151
+ // }
152
+ }
153
+
154
+ // A worker that acks messages only if processed succesfully
155
+ // var channel;
156
+ startWorker(callback) {
157
+ var that = this;
158
+
159
+ that.amqpConn.createChannel(function(err, ch) {
160
+ if (that.closeOnErr(err)) return;
161
+ ch.on("error", function(err) {
162
+ if (this.debug) {console.log("[JobWorker] AMQP channel error", err);}
163
+ });
164
+ ch.on("close", function() {
165
+ if (this.debug) {console.log("[JobWorker] AMQP channel closed");}
166
+ });
167
+ ch.prefetch(10);
168
+ ch.assertExchange(that.exchange, 'topic', {
169
+ durable: false
170
+ });
171
+
172
+ if (that.debug) {console.log("[JobWorker] AMQP that.topic", that.topic);}
173
+ ch.assertQueue(that.topic, { durable: false }, function(err, _ok) {
174
+ if (that.closeOnErr(err)) return;
175
+ ch.bindQueue(_ok.queue, that.exchange, that.defaultTopic, {}, function(err3, oka) {
176
+ if (that.debug) {console.log("[JobWorker] Queue bind: "+_ok.queue+ " err: "+err3+ " key: " + that.defaultTopic );}
177
+ // if (this.debug) {console.log("Data queue", oka)
178
+ });
179
+ ch.bindQueue(_ok.queue, that.exchange, "functions", {}, function(err3, oka) {
180
+ if (that.debug) {console.log("[JobWorker] Queue bind: "+_ok.queue+ " err: "+err3+ " key: " + "functions" );}
181
+ // if (this.debug) {console.log("Data queue", oka)
182
+ });
183
+
184
+ if (that.debug) {console.log("[JobWorker] AMQP that.topic", that.topic);}
185
+ ch.consume(that.topic, that.processMsg2, { noAck: true });
186
+ // ch.consume("jobs", that.processMsg, { noAck: false });
187
+ if (that.debug) {console.log("[JobWorker] Worker is started");}
188
+
189
+ if (callback) {
190
+ callback();
191
+ if (that.debug) {console.log("[JobWorker] called callback worker");}
192
+ }
193
+ });
194
+
195
+
196
+ });
197
+ }
198
+
199
+
200
+
201
+ // work(msg, cb) {
202
+ // const message_string = msg.content.toString();
203
+ // const topic = msg.fields.routingKey //.replace(/[.]/g, '/');
204
+
205
+ // if (this.debug) {console.log("Got msg topic:" + topic);
206
+
207
+ // if (this.debug) {console.log("Got msg:"+ message_string + " topic:" + topic);
208
+
209
+ // if (topic === 'subscription_run') {
210
+ // if (this.debug) {console.log("here topic:" + topic);
211
+ // // requestEvent.emit('request.create.queue', msg.content);
212
+ // subscriptionEvent.emit('subscription.run.queue', JSON.parse(message_string));
213
+ // }
214
+ // cb(true);
215
+ // if (this.debug) {console.log("okookokkkkkkk msg:");
216
+ // }
217
+
218
+ processMsg2(msg) {
219
+
220
+ // console.log("processMsg2:", msg);
221
+
222
+ const message_string = msg.content.toString();
223
+ // console.log("processMsg2.1:", msg);
224
+
225
+ const topic = msg.fields.routingKey //.replace(/[.]/g, '/');
226
+ // console.log("processMsg2.2:", msg);
227
+
228
+ // if (this.debug) {console.log("Got msg topic:" + topic);} //this is undefined in this method
229
+ // console.log("Got msg topic:" + topic);
230
+
231
+ // if (this.debug) {console.log("Got msg1:"+ message_string + " topic:" + topic);}
232
+ // console.log("Got msg1:"+ message_string + " topic:" + topic);
233
+
234
+ if (topic === 'functions') {
235
+ // if (this.debug) {console.log("Got msg2:"+ JSON.stringify(message_string) + " topic:" + topic);}
236
+ // console.log("Got msg2:"+ JSON.stringify(message_string) + " topic:" + topic);
237
+
238
+ var fdata = JSON.parse(message_string)
239
+
240
+ // if (this.debug) {console.log("Got msg3:"+ fdata.function + " fdata.function:", fdata.payload);}
241
+
242
+
243
+
244
+ /*
245
+
246
+ // var fields = Object.keys(fdata.payload).map((key) => [key, fdata.payload[key]]);
247
+
248
+ // var fields = Object.keys(fdata.payload)
249
+
250
+ // if (this.debug) {console.log("Got fields:"+ fields );
251
+
252
+ // eval(fdata.function)
253
+
254
+ */
255
+
256
+ if (fdata.function) {
257
+ var fn = new Function("payload", fdata.function);
258
+
259
+ // if (this.debug) {console.log("Got fn:"+ fn);}
260
+
261
+ /*
262
+ // var fn = new Function(fields, fdata.function);
263
+
264
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/Function
265
+ // var fn = new Function("name",'if (this.debug) {console.log("ciao: " + name);');
266
+ // fn("andrea")
267
+
268
+ // var dataArray = Object.keys(fdata.payload).map(function(k){return fdata.payload[k]});
269
+ // if (this.debug) {console.log("Got dataArray:", dataArray );
270
+
271
+ // fn(dataArray);
272
+ */
273
+
274
+
275
+ var ret = fn(fdata.payload)
276
+ // if (this.debug) {console.log("Got ret:"+ ret);}
277
+ // console.log("Got ret:"+ ret);
278
+
279
+ }
280
+
281
+ // else {
282
+ // console.log("no function found");
283
+ // }
284
+
285
+
286
+ }
287
+
288
+ // if (topic === 'subscription_run') {
289
+ // if (this.debug) {console.log("here topic:" + topic);
290
+ // // requestEvent.emit('request.create.queue', msg.content);
291
+ // subscriptionEvent.emit('subscription.run.queue', JSON.parse(message_string));
292
+ // }
293
+
294
+
295
+ // serve?
296
+ // if (this.debug) {console.log("listeners.length:" + listeners.length);}
297
+
298
+ if (listeners && listeners.length>0) {
299
+ for( var i = 0; i< listeners.length; i++) {
300
+ // if (this.debug) {console.log("listeners[i]:" + listeners[i]);}
301
+ listeners[i](fdata);
302
+ }
303
+ }
304
+
305
+ // if (this.debug) {console.log("listeners", this.listeners);
306
+ }
307
+ // processMsg(msg) {
308
+ // if (this.debug) {console.log("processMsg msg:", msg);
309
+
310
+ // var that = this;
311
+ // that.work(msg, function(ok) {
312
+ // try {
313
+ // if (ok)
314
+ // ch.ack(msg);
315
+ // else
316
+ // ch.reject(msg, true);
317
+ // } catch (e) {
318
+ // that.closeOnErr(e);
319
+ // }
320
+ // });
321
+ // }
322
+
323
+ closeOnErr(err) {
324
+ if (!err) return false;
325
+ if (this.debug) {console.log("[JobWorker] AMQP error", err);}
326
+ this.amqpConn.close();
327
+ return true;
328
+ }
329
+
330
+ sendJson(data, topic, callback) {
331
+
332
+ this.publish(this.exchange, topic || this.defaultTopic, Buffer.from(JSON.stringify(data)), (err, ok) => {
333
+ if (callback) {
334
+ callback(err, ok);
335
+ }
336
+ });
337
+ }
338
+
339
+ send(string, topic) {
340
+ if (this.debug) {console.log("[JobWorker] send(string): ", string);}
341
+ this.publish(this.exchange, topic || this.defaultTopic, Buffer.from(string));
342
+ }
343
+
344
+ on(fn) {
345
+ listeners.push(fn);
346
+ }
347
+
348
+
349
+
350
+ }
351
+
352
+
353
+
354
+
355
+ module.exports = QueueManager;