UNPKG

@tiledesk/tiledesk-server

Version:
485 lines (392 loc) 17.1 kB
var amqp = require('amqplib/callback_api'); var winston = require('../../config/winston'); const requestEvent = require('../../event/requestEvent'); const messageEvent = require('../../event/messageEvent'); const leadEvent = require('../../event/leadEvent'); const botEvent = require('../../event/botEvent'); const authEvent = require('../../event/authEvent'); // https://elements.heroku.com/addons/cloudamqp // https://gist.github.com/carlhoerberg/006b01ac17a0a94859ba#file-reconnect-js // http://www.rabbitmq.com/tutorials/tutorial-one-javascript.html // if the connection is closed or fails to be established at all, we will reconnect var amqpConn = null; var url = process.env.CLOUDAMQP_URL + "?heartbeat=60" || "amqp://localhost"; // attento devi aggiornare configMap di PRE E PROD // var url = process.env.AMQP_URL + "?heartbeat=60" || "amqp://localhost?heartbeat=60"; // var durable = true; var durable = false; // if (process.env.ENABLE_DURABLE_QUEUE == false || process.env.ENABLE_DURABLE_QUEUE == "false") { // durable = false; // } var persistent = false; if (process.env.ENABLE_PERSISTENT_QUEUE == true || process.env.ENABLE_PERSISTENT_QUEUE == "true") { persistent = true; } var exchange = process.env.QUEUE_EXCHANGE_TOPIC || 'amq.topic'; var queueName = process.env.QUEUE_NAME || 'jobs'; winston.info("Durable queue: " + durable + " Persistent queue: " + persistent + " Exchange topic: " + exchange+ " Queue name: " + queueName); function start() { amqp.connect(url, function(err, conn) { if (err) { winston.error("[AMQP]", err); return setTimeout(start, 1000); } conn.on("error", function(err) { if (err.message !== "Connection closing") { winston.error("[AMQP] conn error", err); } }); conn.on("close", function() { winston.error("[AMQP] reconnecting"); return setTimeout(start, 1000); }); winston.info("[AMQP] connected"); amqpConn = conn; whenConnected(); }); } function whenConnected() { startPublisher(); let jobWorkerEnabled = false; if (process.env.JOB_WORKER_ENABLED=="true" || process.env.JOB_WORKER_ENABLED == true) { jobWorkerEnabled = true; } winston.info("JobsManager jobWorkerEnabled: "+ jobWorkerEnabled); if (jobWorkerEnabled == false) { winston.info("Queue Reconnect starts queue worker (queue observer)"); startWorker(); } else { winston.info("Queue Reconnect without queue worker (queue observer) because external worker is enabled"); } } var pubChannel = null; var offlinePubQueue = []; function startPublisher() { amqpConn.createConfirmChannel(function(err, ch) { if (closeOnErr(err)) return; ch.on("error", function(err) { winston.error("[AMQP] channel error", err); }); ch.on("close", function() { winston.info("[AMQP] channel closed"); }); pubChannel = ch; while (true) { var m = offlinePubQueue.shift(); if (!m) break; publish(m[0], m[1], m[2]); } }); } // method to publish a message, will queue messages internally if the connection is down and resend later function publish(exchange, routingKey, content) { try { pubChannel.publish(exchange, routingKey, content, { persistent: persistent }, // pubChannel.publish(exchange, routingKey, content, { persistent: true }, function(err, ok) { if (err) { winston.error("[AMQP] publish", err); offlinePubQueue.push([exchange, routingKey, content]); pubChannel.connection.close(); } }); } catch (e) { winston.error("[AMQP] publish", e); offlinePubQueue.push([exchange, routingKey, content]); } } // A worker that acks messages only if processed succesfully // var channel; function startWorker() { amqpConn.createChannel(function(err, ch) { if (closeOnErr(err)) return; ch.on("error", function(err) { winston.error("[AMQP] channel error", err); }); ch.on("close", function() { winston.info("[AMQP] channel closed"); }); ch.prefetch(10);//leggila da env ch.assertExchange(exchange, 'topic', { durable: durable // durable: true }); ch.assertQueue(queueName, { durable: durable }, function(err, _ok) { // ch.assertQueue("jobs", { durable: true }, function(err, _ok) { if (closeOnErr(err)) return; ch.bindQueue(_ok.queue, exchange, "request_create", {}, function(err3, oka) { winston.info("Queue bind: "+_ok.queue+ " err: "+err3+ " key: request_create"); winston.info("Data queue", oka) }); ch.bindQueue(_ok.queue, exchange, "request_update_preflight", {}, function(err3, oka) { winston.info("Queue bind: "+_ok.queue+ " err: "+err3+ " key: request_update_preflight"); winston.info("Data queue", oka) }); ch.bindQueue(_ok.queue, exchange, "request_participants_update", {}, function(err3, oka) { winston.info("Queue bind: "+_ok.queue+ " err: "+err3+ " key: request_participants_update"); winston.info("Data queue", oka) }); ch.bindQueue(_ok.queue, exchange, "request_participants_join", {}, function(err3, oka) { winston.info("Queue bind: "+_ok.queue+ " err: "+err3+ " key: request_participants_join"); winston.info("Data queue", oka) }); ch.bindQueue(_ok.queue, exchange, "request_participants_leave", {}, function(err3, oka) { winston.info("Queue bind: "+_ok.queue+ " err: "+err3+ " key: request_participants_leave"); winston.info("Data queue", oka) }); ch.bindQueue(_ok.queue, exchange, "request_update", {}, function(err3, oka) { winston.info("Queue bind: "+_ok.queue+ " err: "+err3+ " key: request_update"); winston.info("Data queue", oka) }); ch.bindQueue(_ok.queue, exchange, "request_close", {}, function(err3, oka) { winston.info("Queue bind: "+_ok.queue+ " err: "+err3+ " key: request_close"); winston.info("Data queue", oka) }); ch.bindQueue(_ok.queue, exchange, "request_close_extended", {}, function(err3, oka) { winston.info("Queue bind: "+_ok.queue+ " err: "+err3+ " key: request_close_extended"); winston.info("Data queue", oka) }); ch.bindQueue(_ok.queue, exchange, "message_create", {}, function(err3, oka) { winston.info("Queue bind: "+_ok.queue+ " err: "+err3+ " key: message_create"); winston.info("Data queue", oka) }); ch.bindQueue(_ok.queue, exchange, "project_user_update", {}, function(err3, oka) { winston.info("Queue bind: "+_ok.queue+ " err: "+err3+ " key: project_user_update"); winston.info("Data queue", oka) }); ch.bindQueue(_ok.queue, exchange, "faqbot_update", {}, function(err3, oka) { winston.info("Queue bind: "+_ok.queue+ " err: "+err3+ " key: faqbot_update"); winston.info("Data queue", oka) }); ch.bindQueue(_ok.queue, exchange, "lead_create", {}, function(err3, oka) { winston.info("Queue bind: "+_ok.queue+ " err: "+err3+ " key: lead_create"); winston.info("Data queue", oka) }); ch.bindQueue(_ok.queue, exchange, "lead_update", {}, function(err3, oka) { winston.info("Queue bind: "+_ok.queue+ " err: "+err3+ " key: lead_update"); winston.info("Data queue", oka) }); ch.bindQueue(_ok.queue, exchange, "lead_fullname_email_update", {}, function(err3, oka) { winston.info("Queue bind: "+_ok.queue+ " err: "+err3+ " key: lead_fullname_email_update"); winston.info("Data queue", oka) }); ch.consume(queueName, processMsg, { noAck: false }); winston.info("Worker is started"); }); function processMsg(msg) { work(msg, function(ok) { try { if (ok) ch.ack(msg); else ch.reject(msg, true); } catch (e) { closeOnErr(e); } }); } }); } function work(msg, cb) { const message_string = msg.content.toString(); const topic = msg.fields.routingKey //.replace(/[.]/g, '/'); winston.debug("Got msg topic:" + topic); winston.debug("Got msg:"+ message_string + " topic:" + topic); if (topic === 'request_create') { winston.debug("reconnect here topic:" + topic); // requestEvent.emit('request.create.queue', msg.content); requestEvent.emit('request.create.queue', JSON.parse(message_string)); } if (topic === 'request_update') { winston.debug("reconnect here topic:" + topic); // requestEvent.emit('request.update.queue', msg.content); requestEvent.emit('request.update.queue', JSON.parse(message_string)); } if (topic === 'request_update_preflight') { winston.debug("reconnect here topic:" + topic); // requestEvent.emit('request.update.queue', msg.content); requestEvent.emit('request.update.preflight.queue', JSON.parse(message_string)); } if (topic === 'request_participants_join') { winston.debug("reconnect here topic:" + topic); // requestEvent.emit('request.update.queue', msg.content); requestEvent.emit('request.participants.join.queue', JSON.parse(message_string)); } if (topic === 'request_participants_leave') { winston.debug("reconnect here topic:" + topic); // requestEvent.emit('request.update.queue', msg.content); requestEvent.emit('request.participants.leave.queue', JSON.parse(message_string)); } if (topic === 'request_participants_update') { winston.debug("reconnect here topic:" + topic); // requestEvent.emit('request.update.queue', msg.content); requestEvent.emit('request.participants.update.queue', JSON.parse(message_string)); } if (topic === 'request_close') { winston.debug("reconnect here topic:" + topic); // requestEvent.emit('request.update.queue', msg.content); requestEvent.emit('request.close.queue', JSON.parse(message_string)); } if (topic === 'request_close_extended') { winston.debug("reconnect here topic:" + topic); // requestEvent.emit('request.update.queue', msg.content); requestEvent.emit('request.close.extended.queue', JSON.parse(message_string)); } if (topic === 'message_create') { winston.debug("reconnect here topic:" + topic); // requestEvent.emit('request.create.queue', msg.content); messageEvent.emit('message.create.queue', JSON.parse(message_string)); } if (topic === 'project_user_update') { winston.debug("reconnect here topic:" + topic); // requestEvent.emit('request.create.queue', msg.content); authEvent.emit('project_user.update.queue', JSON.parse(message_string)); } if (topic === 'faqbot_update') { winston.debug("reconnect here topic faqbot_update:" + topic); // requestEvent.emit('request.update.queue', msg.content); botEvent.emit('faqbot.update.queue', JSON.parse(message_string)); } if (topic === 'lead_create') { winston.debug("reconnect here topic lead_create:" + topic); // requestEvent.emit('request.update.queue', msg.content); leadEvent.emit('lead.create.queue', JSON.parse(message_string)); } if (topic === 'lead_update') { winston.debug("reconnect here topic lead_update:" + topic); // requestEvent.emit('request.update.queue', msg.content); leadEvent.emit('lead.update.queue', JSON.parse(message_string)); } if (topic === 'lead_fullname_email_update') { winston.debug("reconnect here topic lead_fullname_email_update:" + topic); // requestEvent.emit('request.update.queue', msg.content); leadEvent.emit('lead.fullname.email.update.queue', JSON.parse(message_string)); } cb(true); // WebSocket.cb(true); // requestEvent.on(msg.KEYYYYYYY+'.ws', msg.content); } function closeOnErr(err) { if (!err) return false; winston.error("[AMQP] error", err); amqpConn.close(); return true; } // setInterval(function() { // var d = new Date(); // publish(exchange, "request_create", Buffer.from("work work work: "+d)); // publish(exchange, "request_update", Buffer.from("work2 work work: "+d)); // }, 1000); function listen() { // http://www.squaremobius.net/amqp.node/channel_api.html // https://docs.parseplatform.org/parse-server/guide/#scalability requestEvent.on('request.create', function(request) { setImmediate(() => { winston.debug("reconnect request.create") publish(exchange, "request_create", Buffer.from(JSON.stringify(request))); }); }); requestEvent.on('request.update', function(request) { setImmediate(() => { winston.debug("reconnect request.update") publish(exchange, "request_update", Buffer.from(JSON.stringify(request))); }); }); requestEvent.on('request.participants.join', function(request) { setImmediate(() => { publish(exchange, "request_participants_join", Buffer.from(JSON.stringify(request))); winston.debug("reconnect participants.join published") }); }); requestEvent.on('request.participants.leave', function(request) { setImmediate(() => { publish(exchange, "request_participants_leave", Buffer.from(JSON.stringify(request))); winston.debug("reconnect participants.leave published") }); }); requestEvent.on('request.participants.update', function(request) { setImmediate(() => { publish(exchange, "request_participants_update", Buffer.from(JSON.stringify(request))); winston.debug("reconnect participants.update published") }); }); requestEvent.on('request.update.preflight', function(request) { setImmediate(() => { // winston.info("reconnect request.update.preflight") publish(exchange, "request_update_preflight", Buffer.from(JSON.stringify(request))); winston.debug("reconnect request.update.preflight published") }); }); // winston.debug("sub to reconnect request.close"); requestEvent.on('request.close', function(request) { setImmediate(() => { winston.debug("reconnect request.close"); publish(exchange, "request_close", Buffer.from(JSON.stringify(request))); }); }); requestEvent.on('request.close.extended', function(request) { setImmediate(() => { publish(exchange, "request_close_extended", Buffer.from(JSON.stringify(request))); }); }); messageEvent.on('message.create', function(message) { setImmediate(() => { publish(exchange, "message_create", Buffer.from(JSON.stringify(message))); }); }); authEvent.on('project_user.update',function(data) { setImmediate(() => { let user = undefined; let body = undefined; if (data.req ) { if (data.req.user) { //i think is null from chat21webhook user = data.req.user; } if (data.req.body) { body = data.req.body; } } var dat = {updatedProject_userPopulated: data.updatedProject_userPopulated, req: {user: user, body: body}}; //remove request winston.debug("dat",dat); publish(exchange, "project_user_update", Buffer.from(JSON.stringify(dat))); }); }); botEvent.on('faqbot.update', function(bot) { setImmediate(() => { winston.debug("reconnect faqbot.update") publish(exchange, "faqbot_update", Buffer.from(JSON.stringify(bot))); winston.debug("reconnect: "+ Buffer.from(JSON.stringify(bot))) }); }); leadEvent.on('lead.create', function(lead) { setImmediate(() => { winston.debug("reconnect lead.create") publish(exchange, "lead_create", Buffer.from(JSON.stringify(lead))); winston.debug("reconnect: "+ Buffer.from(JSON.stringify(lead))) }); }); leadEvent.on('lead.update', function(lead) { setImmediate(() => { winston.debug("reconnect lead.update") publish(exchange, "lead_update", Buffer.from(JSON.stringify(lead))); winston.debug("reconnect: "+ Buffer.from(JSON.stringify(lead))) }); }); leadEvent.on('lead.fullname.email.update', function(lead) { setImmediate(() => { winston.debug("reconnect lead.fullname.email.update") publish(exchange, "lead_fullname_email_update", Buffer.from(JSON.stringify(lead))); winston.debug("reconnect: "+ Buffer.from(JSON.stringify(lead))) }); }); } if (process.env.QUEUE_ENABLED === "true") { requestEvent.queueEnabled = true; messageEvent.queueEnabled = true; authEvent.queueEnabled = true; botEvent.queueEnabled = true; leadEvent.queueEnabled = true; listen(); start(); winston.info("Queue enabled. endpoint: " + url ); }