@resolveio/server-lib 20.5.15 → 20.6.1
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.
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var __awaiter=this&&this.__awaiter||function(e,n,r,i){return new(r=r||Promise)(function(o,t){function fulfilled(e){try{step(i.next(e))}catch(e){t(e)}}function rejected(e){try{step(i.throw(e))}catch(e){t(e)}}function step(e){var t;e.done?o(e.value):((t=e.value)instanceof r?t:new r(function(e){e(t)})).then(fulfilled,rejected)}step((i=i.apply(e,n||[])).next())})},__generator=this&&this.__generator||function(n,r){var i,a,s,c={label:0,sent:function(){if(1&s[0])throw s[1];return s[1]},trys:[],ops:[]},l={next:verb(0),throw:verb(1),return:verb(2)};return"function"==typeof Symbol&&(l[Symbol.iterator]=function(){return this}),l;function verb(o){return function(e){var t=[o,e];if(i)throw new TypeError("Generator is already executing.");for(;c=l&&t[l=0]?0:c;)try{if(i=1,a&&(s=2&t[0]?a.return:t[0]?a.throw||((s=a.return)&&s.call(a),0):a.next)&&!(s=s.call(a,t[1])).done)return s;switch(a=0,(t=s?[2&t[0],s.value]:t)[0]){case 0:case 1:s=t;break;case 4:return c.label++,{value:t[1],done:!1};case 5:c.label++,a=t[1],t=[0];continue;case 7:t=c.ops.pop(),c.trys.pop();continue;default:if(!(s=0<(s=c.trys).length&&s[s.length-1])&&(6===t[0]||2===t[0])){c=0;continue}if(3===t[0]&&(!s||t[1]>s[0]&&t[1]<s[3]))c.label=t[1];else if(6===t[0]&&c.label<s[1])c.label=s[1],s=t;else{if(!(s&&c.label<s[2])){s[2]&&c.ops.pop(),c.trys.pop();continue}c.label=s[2],c.ops.push(t)}}t=r.call(n,c)}catch(e){t=[6,e],a=0}finally{i=s=0}if(5&t[0])throw t[1];return{value:t[0]?t[1]:void 0,done:!0}}}},axios_1=(Object.defineProperty(exports,"__esModule",{value:!0}),exports.MonitorFunction=exports.MonitorManagerFunction=exports.MonitorMongo=exports.MonitorManager=void 0,require("axios")),monitor_cpu_collection_1=require("../collections/monitor-cpu.collection"),monitor_memory_collection_1=require("../collections/monitor-memory.collection"),monitor_mongo_collection_1=require("../collections/monitor-mongo.collection"),resolveio_server_app_1=require("../resolveio-server-app"),common_1=require("../util/common"),monitor_function_collection_1=require("../collections/monitor-function.collection"),os=require("os"),MAX_BATCH_SIZE=8388608,MonitorManager=function(){function MonitorManager(){this._instanceHostname="",this._monitorData=[],this._instanceHostname=os.hostname().replace(/\./g,"-"),this.setupIntervals(),this.setupEventLoop()}return MonitorManager.prototype.cpuAverage=function(){for(var e=0,t=0,o=os.cpus(),n=0,r=o.length;n<r;n++){var i,a=o[n];for(i in a.times)t+=a.times[i];e+=a.times.idle}return{idle:e/o.length,total:t/o.length}},MonitorManager.prototype.setupIntervals=function(){return __awaiter(this,void 0,void 0,function(){var t,n,r=this;return __generator(this,function(e){switch(e.label){case 0:if("https://resolveio.com"===resolveio_server_app_1.ResolveIOServer.getServerConfig().ROOT_URL||"http://localhost:4200"===resolveio_server_app_1.ResolveIOServer.getServerConfig().ROOT_URL)return[3,4];e.label=1;case 1:return e.trys.push([1,3,,4]),[4,axios_1.default.get("http://169.254.169.254/latest/meta-data/instance-id")];case 2:return t=e.sent(),setInterval(function(){return __awaiter(r,void 0,void 0,function(){return __generator(this,function(e){switch(e.label){case 0:return e.trys.push([0,2,,3]),[4,axios_1.default.post("https://backend.resolveio.com/api/health",{type:"application",id_aws_instance:t.data,version:"number"==typeof process.env.APP_VERSION?process.env.APP_VERSION.toString():process.env.APP_VERSION,version_key:process.env.APP_VERSION_KEY})];case 1:return e.sent(),[3,3];case 2:return e.sent(),[3,3];case 3:return[2]}})})},1e4),[3,4];case 3:return e.sent(),[3,4];case 4:return n=this.cpuAverage(),setInterval(function(){var e=new Date,t=r.cpuAverage(),o=1-(t.idle-n.idle)/(t.total-n.total),o=("https://resolveio.com"===resolveio_server_app_1.ResolveIOServer.getServerConfig().ROOT_URL||"http://localhost:4200"===resolveio_server_app_1.ResolveIOServer.getServerConfig().ROOT_URL?monitor_cpu_collection_1.MonitorCPUs.create({_id:(0,common_1.objectIdHexString)(),metadata:{instance:r._instanceHostname,client:resolveio_server_app_1.ResolveIOServer.getServerConfig().CLIENT_NAME},date:e,app:o,system:os.loadavg()[0]}):r.pushMonitorData({type:"monitor-cpu",data:{metadata:{instance:r._instanceHostname,client:resolveio_server_app_1.ResolveIOServer.getServerConfig().CLIENT_NAME},date:e,app:o,system:os.loadavg()[0]}}),n=t,process.memoryUsage());"https://resolveio.com"===resolveio_server_app_1.ResolveIOServer.getServerConfig().ROOT_URL||"http://localhost:4200"===resolveio_server_app_1.ResolveIOServer.getServerConfig().ROOT_URL?monitor_memory_collection_1.MonitorMemorys.create({_id:(0,common_1.objectIdHexString)(),metadata:{instance:r._instanceHostname,client:resolveio_server_app_1.ResolveIOServer.getServerConfig().CLIENT_NAME},date:e,physical_total:o.heapTotal,physical_used:o.heapUsed,physical_free:os.freemem(),virtual:o.rss,private:o.external,physical:os.totalmem()}):r.pushMonitorData({type:"monitor-memory",data:{metadata:{instance:r._instanceHostname,client:resolveio_server_app_1.ResolveIOServer.getServerConfig().CLIENT_NAME},date:e,physical_total:o.heapTotal,physical_used:o.heapUsed,physical_free:os.freemem(),virtual:o.rss,private:o.external,physical:os.totalmem(),type:"memory"}})},3e3),[2]}})})},MonitorManager.prototype.addMongoTracker=function(e){"https://resolveio.com"===resolveio_server_app_1.ResolveIOServer.getServerConfig().ROOT_URL||"http://localhost:4200"===resolveio_server_app_1.ResolveIOServer.getServerConfig().ROOT_URL?e.collection.startsWith("monitor-")||monitor_mongo_collection_1.MonitorMongos.create({_id:(0,common_1.objectIdHexString)(),metadata:{instance:this._instanceHostname,client:resolveio_server_app_1.ResolveIOServer.getServerConfig().CLIENT_NAME},date:new Date(e.date),method:e.method,doc_collection:e.collection,duration:e.duration,query:Buffer.byteLength(e.query,"utf8")<158e5?e.query:"Too Big"}):this._instanceHostname&&this.pushMonitorData({type:"monitor-mongo",data:{metadata:{instance:this._instanceHostname,client:resolveio_server_app_1.ResolveIOServer.getServerConfig().CLIENT_NAME},date:new Date(e.date),method:e.method,doc_collection:e.collection,duration:e.duration,query:Buffer.byteLength(e.query,"utf8")<158e5?e.query:"Too Big"}})},MonitorManager.prototype.addFunctionTracker=function(e){"https://resolveio.com"===resolveio_server_app_1.ResolveIOServer.getServerConfig().ROOT_URL||"http://localhost:4200"===resolveio_server_app_1.ResolveIOServer.getServerConfig().ROOT_URL?monitor_function_collection_1.MonitorFunctions.create({_id:(0,common_1.objectIdHexString)(),metadata:{instance:this._instanceHostname,client:resolveio_server_app_1.ResolveIOServer.getServerConfig().CLIENT_NAME},date:new Date(e.startTime),type:e.functionType,name:e.functionName,user:e.user,duration:e.duration,data:Buffer.byteLength(e.data,"utf8")<158e5?e.data:"Too Big"}):this._instanceHostname&&this.pushMonitorData({type:"monitor-function",data:{metadata:{instance:this._instanceHostname,client:resolveio_server_app_1.ResolveIOServer.getServerConfig().CLIENT_NAME},date:new Date(e.startTime),type:e.functionType,name:e.functionName,user:e.user,duration:e.duration,data:Buffer.byteLength(e.data,"utf8")<158e5?e.data:"Too Big"}})},MonitorManager.prototype.pushMonitorData=function(e){this._monitorData.push(e),this.estimateBatchSize()>=MAX_BATCH_SIZE&&this.flushMonitorData()},MonitorManager.prototype.estimateBatchSize=function(){return this._monitorData.reduce(function(e,t){return e+Buffer.byteLength(JSON.stringify(t))},0)},MonitorManager.prototype.setupEventLoop=function(){var e=this;setInterval(function(){0<e._monitorData.length&&e.flushMonitorData()},2500)},MonitorManager.prototype.flushMonitorData=function(){for(var e=[],t=0;0<this._monitorData.length&&t<MAX_BATCH_SIZE;){var o=this._monitorData.shift(),n=Buffer.byteLength(JSON.stringify(o));if(MAX_BATCH_SIZE<t+n&&0<e.length){this._monitorData.unshift(o);break}e.push(o),t+=n}try{resolveio_server_app_1.ResolveIOServer.getLocalLogManager().writeLogs(e)}catch(e){console.error(new Date,"MonitorManager","Failed to flush monitor data to file:",e)}},MonitorManager}(),MonitorMongo=(exports.MonitorManager=MonitorManager,function(){function MonitorMongo(e,t,o){this._startTime=0,this._method="",this._collection="",this._query="",this._startTime=Date.now(),this._method=e,this._collection=t,this._query=o}return MonitorMongo.prototype.finish=function(){var e=Date.now(),e={date:new Date(e),method:this._method,collection:this._collection,query:this._query,duration:e-this._startTime};resolveio_server_app_1.ResolveIOServer.getMainServer().getMonitorManager().addMongoTracker(e)},MonitorMongo}()),MonitorManagerFunction=(exports.MonitorMongo=MonitorMongo,function(){function MonitorManagerFunction(){this._functionCnt=0,this._functions=[],this._functionLastCompletedWS={}}return MonitorManagerFunction.prototype.startMonitorFunction=function(e,t,o,n,r){e=new MonitorFunction(this._functionCnt++,e,t,o,n,r);return this._functions.push(e),e.id},MonitorManagerFunction.prototype.finishMonitorFunction=function(t){var e=this._functions.find(function(e){return e.id===t});e&&(e.finish(),this._functionLastCompleted=e,this._functionLastCompletedWS[e.id_socket]=e,this._functions.splice(this._functions.map(function(e){return e.id}).indexOf(t),1))},MonitorManagerFunction.prototype.getActiveMonitorFunctions=function(){return this._functions},MonitorManagerFunction.prototype.getLastCompletedMonitorFunction=function(){return this._functionLastCompleted},MonitorManagerFunction.prototype.getLastCompletedMonitorFunctionWS=function(){return this._functionLastCompletedWS},MonitorManagerFunction}()),MonitorFunction=(exports.MonitorManagerFunction=MonitorManagerFunction,function(){function MonitorFunction(e,t,o,n,r,i){var a=this;this._timer=null,this.duration=0,this.startTime=null,this.endTime=null,this.lastTime=null,this.id_socket="",this.id=0,this.id=e,this.startTime=new Date,this.functionType=t,this.functionName=o,this.user=n,this.id_socket=r,this.data=i,this.lastTime=new Date,this._timer=setInterval(function(){var e=Date.now()-a.lastTime.getTime();e>a.duration&&(a.duration=e),a.lastTime=new Date},1e3)}return MonitorFunction.prototype.finish=function(){this._timer&&(clearInterval(this._timer),this._timer=null),this.endTime=new Date,this.duration,resolveio_server_app_1.ResolveIOServer.getMainServer().getMonitorManager().addFunctionTracker(this)},MonitorFunction}());exports.MonitorFunction=MonitorFunction;
|
|
1
|
+
"use strict";var __awaiter=this&&this.__awaiter||function(e,n,r,i){return new(r=r||Promise)(function(o,t){function fulfilled(e){try{step(i.next(e))}catch(e){t(e)}}function rejected(e){try{step(i.throw(e))}catch(e){t(e)}}function step(e){var t;e.done?o(e.value):((t=e.value)instanceof r?t:new r(function(e){e(t)})).then(fulfilled,rejected)}step((i=i.apply(e,n||[])).next())})},__generator=this&&this.__generator||function(n,r){var i,a,s,c={label:0,sent:function(){if(1&s[0])throw s[1];return s[1]},trys:[],ops:[]},l={next:verb(0),throw:verb(1),return:verb(2)};return"function"==typeof Symbol&&(l[Symbol.iterator]=function(){return this}),l;function verb(o){return function(e){var t=[o,e];if(i)throw new TypeError("Generator is already executing.");for(;c=l&&t[l=0]?0:c;)try{if(i=1,a&&(s=2&t[0]?a.return:t[0]?a.throw||((s=a.return)&&s.call(a),0):a.next)&&!(s=s.call(a,t[1])).done)return s;switch(a=0,(t=s?[2&t[0],s.value]:t)[0]){case 0:case 1:s=t;break;case 4:return c.label++,{value:t[1],done:!1};case 5:c.label++,a=t[1],t=[0];continue;case 7:t=c.ops.pop(),c.trys.pop();continue;default:if(!(s=0<(s=c.trys).length&&s[s.length-1])&&(6===t[0]||2===t[0])){c=0;continue}if(3===t[0]&&(!s||t[1]>s[0]&&t[1]<s[3]))c.label=t[1];else if(6===t[0]&&c.label<s[1])c.label=s[1],s=t;else{if(!(s&&c.label<s[2])){s[2]&&c.ops.pop(),c.trys.pop();continue}c.label=s[2],c.ops.push(t)}}t=r.call(n,c)}catch(e){t=[6,e],a=0}finally{i=s=0}if(5&t[0])throw t[1];return{value:t[0]?t[1]:void 0,done:!0}}}},axios_1=(Object.defineProperty(exports,"__esModule",{value:!0}),exports.MonitorFunction=exports.MonitorManagerFunction=exports.MonitorMongo=exports.MonitorManager=void 0,require("axios")),monitor_cpu_collection_1=require("../collections/monitor-cpu.collection"),monitor_memory_collection_1=require("../collections/monitor-memory.collection"),monitor_mongo_collection_1=require("../collections/monitor-mongo.collection"),resolveio_server_app_1=require("../resolveio-server-app"),common_1=require("../util/common"),monitor_function_collection_1=require("../collections/monitor-function.collection"),os=require("os"),MAX_BATCH_SIZE=8388608,MonitorManager=function(){function MonitorManager(){this._instanceHostname="",this._monitorData=[],this._instanceHostname=os.hostname().replace(/\./g,"-"),this.setupIntervals(),this.setupEventLoop()}return MonitorManager.prototype.cpuAverage=function(){for(var e=0,t=0,o=os.cpus(),n=0,r=o.length;n<r;n++){var i,a=o[n];for(i in a.times)t+=a.times[i];e+=a.times.idle}return{idle:e/o.length,total:t/o.length}},MonitorManager.prototype.setupIntervals=function(){return __awaiter(this,void 0,void 0,function(){var t,n,r=this;return __generator(this,function(e){switch(e.label){case 0:if("https://resolveio.com"===resolveio_server_app_1.ResolveIOServer.getServerConfig().ROOT_URL||"http://localhost:4200"===resolveio_server_app_1.ResolveIOServer.getServerConfig().ROOT_URL)return[3,4];e.label=1;case 1:return e.trys.push([1,3,,4]),[4,axios_1.default.get("http://169.254.169.254/latest/meta-data/instance-id")];case 2:return t=e.sent(),setInterval(function(){return __awaiter(r,void 0,void 0,function(){return __generator(this,function(e){switch(e.label){case 0:return e.trys.push([0,2,,3]),[4,axios_1.default.post("https://backend.resolveio.com/api/health",{type:"application",id_aws_instance:t.data,version:"number"==typeof process.env.APP_VERSION?process.env.APP_VERSION.toString():process.env.APP_VERSION,version_key:process.env.APP_VERSION_KEY})];case 1:return e.sent(),[3,3];case 2:return e.sent(),[3,3];case 3:return[2]}})})},1e4),[3,4];case 3:return e.sent(),[3,4];case 4:return n=this.cpuAverage(),setInterval(function(){var e=new Date,t=r.cpuAverage(),o=1-(t.idle-n.idle)/(t.total-n.total),o=("https://resolveio.com"===resolveio_server_app_1.ResolveIOServer.getServerConfig().ROOT_URL||"http://localhost:4200"===resolveio_server_app_1.ResolveIOServer.getServerConfig().ROOT_URL?monitor_cpu_collection_1.MonitorCPUs.create({_id:(0,common_1.objectIdHexString)(),metadata:{instance:r._instanceHostname,client:resolveio_server_app_1.ResolveIOServer.getServerConfig().CLIENT_NAME},date:e,app:o,system:os.loadavg()[0]}):r.pushMonitorData({type:"monitor-cpu",data:{metadata:{instance:r._instanceHostname,client:resolveio_server_app_1.ResolveIOServer.getServerConfig().CLIENT_NAME},date:e,app:o,system:os.loadavg()[0]}}),n=t,process.memoryUsage());"https://resolveio.com"===resolveio_server_app_1.ResolveIOServer.getServerConfig().ROOT_URL||"http://localhost:4200"===resolveio_server_app_1.ResolveIOServer.getServerConfig().ROOT_URL?monitor_memory_collection_1.MonitorMemorys.create({_id:(0,common_1.objectIdHexString)(),metadata:{instance:r._instanceHostname,client:resolveio_server_app_1.ResolveIOServer.getServerConfig().CLIENT_NAME},date:e,physical_total:o.heapTotal,physical_used:o.heapUsed,physical_free:os.freemem(),virtual:o.rss,private:o.external,physical:os.totalmem()}):r.pushMonitorData({type:"monitor-memory",data:{metadata:{instance:r._instanceHostname,client:resolveio_server_app_1.ResolveIOServer.getServerConfig().CLIENT_NAME},date:e,physical_total:o.heapTotal,physical_used:o.heapUsed,physical_free:os.freemem(),virtual:o.rss,private:o.external,physical:os.totalmem(),type:"memory"}})},3e3),[2]}})})},MonitorManager.prototype.addMongoTracker=function(e){"https://resolveio.com"===resolveio_server_app_1.ResolveIOServer.getServerConfig().ROOT_URL||"http://localhost:4200"===resolveio_server_app_1.ResolveIOServer.getServerConfig().ROOT_URL?e.collection.startsWith("monitor-")||monitor_mongo_collection_1.MonitorMongos.create({_id:(0,common_1.objectIdHexString)(),metadata:{instance:this._instanceHostname,client:resolveio_server_app_1.ResolveIOServer.getServerConfig().CLIENT_NAME},date:new Date(e.date),method:e.method,doc_collection:e.collection,duration:e.duration,query:Buffer.byteLength(e.query,"utf8")<158e5?e.query:"Too Big"}):this._instanceHostname&&this.pushMonitorData({type:"monitor-mongo",data:{metadata:{instance:this._instanceHostname,client:resolveio_server_app_1.ResolveIOServer.getServerConfig().CLIENT_NAME},date:new Date(e.date),method:e.method,doc_collection:e.collection,duration:e.duration,query:Buffer.byteLength(e.query,"utf8")<158e5?e.query:"Too Big"}})},MonitorManager.prototype.addFunctionTracker=function(e){"string"!=typeof e.data&&(e.data=JSON.stringify(e.data)),"https://resolveio.com"===resolveio_server_app_1.ResolveIOServer.getServerConfig().ROOT_URL||"http://localhost:4200"===resolveio_server_app_1.ResolveIOServer.getServerConfig().ROOT_URL?monitor_function_collection_1.MonitorFunctions.create({_id:(0,common_1.objectIdHexString)(),metadata:{instance:this._instanceHostname,client:resolveio_server_app_1.ResolveIOServer.getServerConfig().CLIENT_NAME},date:new Date(e.startTime),type:e.functionType,name:e.functionName,user:e.user,duration:e.duration,data:Buffer.byteLength(e.data,"utf8")<158e5?e.data:"Too Big"}):this._instanceHostname&&this.pushMonitorData({type:"monitor-function",data:{metadata:{instance:this._instanceHostname,client:resolveio_server_app_1.ResolveIOServer.getServerConfig().CLIENT_NAME},date:new Date(e.startTime),type:e.functionType,name:e.functionName,user:e.user,duration:e.duration,data:Buffer.byteLength(e.data,"utf8")<158e5?e.data:"Too Big"}})},MonitorManager.prototype.pushMonitorData=function(e){this._monitorData.push(e),this.estimateBatchSize()>=MAX_BATCH_SIZE&&this.flushMonitorData()},MonitorManager.prototype.estimateBatchSize=function(){return this._monitorData.reduce(function(e,t){return e+Buffer.byteLength(JSON.stringify(t))},0)},MonitorManager.prototype.setupEventLoop=function(){var e=this;setInterval(function(){0<e._monitorData.length&&e.flushMonitorData()},2500)},MonitorManager.prototype.flushMonitorData=function(){for(var e=[],t=0;0<this._monitorData.length&&t<MAX_BATCH_SIZE;){var o=this._monitorData.shift(),n=Buffer.byteLength(JSON.stringify(o));if(MAX_BATCH_SIZE<t+n&&0<e.length){this._monitorData.unshift(o);break}e.push(o),t+=n}try{resolveio_server_app_1.ResolveIOServer.getLocalLogManager().writeLogs(e)}catch(e){console.error(new Date,"MonitorManager","Failed to flush monitor data to file:",e)}},MonitorManager}(),MonitorMongo=(exports.MonitorManager=MonitorManager,function(){function MonitorMongo(e,t,o){this._startTime=0,this._method="",this._collection="",this._query="",this._startTime=Date.now(),this._method=e,this._collection=t,this._query=o}return MonitorMongo.prototype.finish=function(){var e=Date.now(),e={date:new Date(e),method:this._method,collection:this._collection,query:this._query,duration:e-this._startTime};resolveio_server_app_1.ResolveIOServer.getMainServer().getMonitorManager().addMongoTracker(e)},MonitorMongo}()),MonitorManagerFunction=(exports.MonitorMongo=MonitorMongo,function(){function MonitorManagerFunction(){this._functionCnt=0,this._functions=[],this._functionLastCompletedWS={}}return MonitorManagerFunction.prototype.startMonitorFunction=function(e,t,o,n,r){e=new MonitorFunction(this._functionCnt++,e,t,o,n,r);return this._functions.push(e),e.id},MonitorManagerFunction.prototype.finishMonitorFunction=function(t){var e=this._functions.find(function(e){return e.id===t});e&&(e.finish(),this._functionLastCompleted=e,this._functionLastCompletedWS[e.id_socket]=e,this._functions.splice(this._functions.map(function(e){return e.id}).indexOf(t),1))},MonitorManagerFunction.prototype.getActiveMonitorFunctions=function(){return this._functions},MonitorManagerFunction.prototype.getLastCompletedMonitorFunction=function(){return this._functionLastCompleted},MonitorManagerFunction.prototype.getLastCompletedMonitorFunctionWS=function(){return this._functionLastCompletedWS},MonitorManagerFunction}()),MonitorFunction=(exports.MonitorManagerFunction=MonitorManagerFunction,function(){function MonitorFunction(e,t,o,n,r,i){var a=this;this._timer=null,this.duration=0,this.startTime=null,this.endTime=null,this.lastTime=null,this.id_socket="",this.id=0,this.id=e,this.startTime=new Date,this.functionType=t,this.functionName=o,this.user=n,this.id_socket=r,this.data=i,this.lastTime=new Date,this._timer=setInterval(function(){var e=Date.now()-a.lastTime.getTime();e>a.duration&&(a.duration=e),a.lastTime=new Date},1e3)}return MonitorFunction.prototype.finish=function(){this._timer&&(clearInterval(this._timer),this._timer=null),this.endTime=new Date,this.duration,resolveio_server_app_1.ResolveIOServer.getMainServer().getMonitorManager().addFunctionTracker(this)},MonitorFunction}());exports.MonitorFunction=MonitorFunction;
|
|
2
2
|
//# sourceMappingURL=monitor.manager.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/managers/monitor.manager.ts"],"names":["axios_1","require","monitor_cpu_collection_1","monitor_memory_collection_1","monitor_mongo_collection_1","resolveio_server_app_1","common_1","monitor_function_collection_1","os","MAX_BATCH_SIZE","MonitorManager","this","_instanceHostname","_monitorData","hostname","replace","setupIntervals","setupEventLoop","prototype","cpuAverage","totalIdle","totalTick","cpus","i","len","length","type","cpu","times","idle","total","ResolveIOServer","getServerConfig","default","get","instanceId_1","_a","sent","setInterval","__awaiter","_this","post","id_aws_instance","data","version","process","env","APP_VERSION","toString","version_key","APP_VERSION_KEY","lastCPU","now","Date","endMeasure","percentageCPU","memUsage","MonitorCPUs","create","_id","objectIdHexString","metadata","instance","client","date","app","system","loadavg","pushMonitorData","memoryUsage","MonitorMemorys","physical_total","heapTotal","physical_used","heapUsed","physical_free","freemem","virtual","rss","private","external","physical","totalmem","addMongoTracker","collection","startsWith","MonitorMongos","method","doc_collection","duration","query","Buffer","byteLength","addFunctionTracker","MonitorFunctions","startTime","functionType","name","functionName","user","push","estimateBatchSize","flushMonitorData","reduce","item","JSON","stringify","batch","batchSize","shift","itemSize","unshift","getLocalLogManager","writeLogs","error","console","MonitorMongo","exports","_startTime","_method","_collection","_query","finish","endTime","mongoMonitor","getMainServer","getMonitorManager","MonitorManagerFunction","_functionCnt","_functions","_functionLastCompletedWS","startMonitorFunction","id_socket","newMonitorFunction","MonitorFunction","id","finishMonitorFunction","monitor","find","a","_functionLastCompleted","splice","map","indexOf","getActiveMonitorFunctions","getLastCompletedMonitorFunction","getLastCompletedMonitorFunctionWS","_timer","lastTime","diff","getTime","clearInterval"],"mappings":"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","file":"monitor.manager.js","sourcesContent":["import axios from 'axios';\nimport { MonitorCPUs } from '../collections/monitor-cpu.collection';\nimport { MonitorMemorys } from '../collections/monitor-memory.collection';\nimport { MonitorMongos } from '../collections/monitor-mongo.collection';\nimport { ResolveIOServer } from '../resolveio-server-app';\nimport { objectIdHexString } from '../util/common';\nimport { LocalLogModel } from './local-log.manager';\nimport { MonitorFunctions } from '../collections/monitor-function.collection';\n\nconst os = require('os');\nconst MAX_BATCH_SIZE = 8 * 1024 * 1024; // 8MB max for safety\n\nexport class MonitorManager {\n\tprivate _instanceHostname = '';\n\tprivate _monitorData: LocalLogModel[] = [];\n\n\tconstructor() {\n\t\tthis._instanceHostname = os.hostname().replace(/\\./g, '-');\n\n\t\tthis.setupIntervals();\n\t\tthis.setupEventLoop();\n\t}\n\n\tcpuAverage() {\n\t\tvar totalIdle = 0, totalTick = 0;\n\t\tvar cpus = os.cpus();\n\n\t\tfor (var i = 0, len = cpus.length; i < len; i++) {\n\t\t\tvar cpu = cpus[i];\n\n\t\t\tfor (let type in cpu.times) {\n\t\t\t\ttotalTick += cpu.times[type];\n\t\t\t}\n\t\t\ttotalIdle += cpu.times.idle;\n\t\t}\n\n\t\treturn {\n\t\t\tidle: totalIdle / cpus.length,\n\t\t\ttotal: totalTick / cpus.length\n\t\t};\n\t}\n\n\tasync setupIntervals() {\n\t\t// Example: If not on production or localhost, do a health check\n\t\tif (\n\t\t\tResolveIOServer.getServerConfig()['ROOT_URL'] !== 'https://resolveio.com'\n\t\t&& ResolveIOServer.getServerConfig()['ROOT_URL'] !== 'http://localhost:4200'\n\t\t) {\n\t\t\ttry {\n\t\t\t\tlet instanceId = await axios.get('http://169.254.169.254/latest/meta-data/instance-id');\n\n\t\t\t\tsetInterval(async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait axios.post('https://backend.resolveio.com/api/health', {\n\t\t\t\t\t\t\ttype: 'application',\n\t\t\t\t\t\t\tid_aws_instance: instanceId.data,\n\t\t\t\t\t\t\tversion: typeof process.env.APP_VERSION === 'number'\n\t\t\t\t\t\t\t\t? (<any>process.env.APP_VERSION).toString()\n\t\t\t\t\t\t\t\t: process.env.APP_VERSION,\n\t\t\t\t\t\t\tversion_key: process.env.APP_VERSION_KEY\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tcatch(e) {}\n\t\t\t\t}, 10000);\n\t\t\t}\n\t\t\tcatch(errHealth) {}\n\t\t}\n\n\t\tlet lastCPU = this.cpuAverage();\n\n\t\tsetInterval(() => {\n\t\t\tlet now = new Date();\n\t\t\tvar endMeasure = this.cpuAverage();\n\t\t\tvar idleDifference = endMeasure.idle - lastCPU.idle;\n\t\t\tvar totalDifference = endMeasure.total - lastCPU.total;\n\t\t\tvar percentageCPU = 1 - idleDifference / totalDifference;\n\n\t\t\t// Original local code\n\t\t\tif (\n\t\t\t\tResolveIOServer.getServerConfig()['ROOT_URL'] === 'https://resolveio.com'\n\t\t\t|| ResolveIOServer.getServerConfig()['ROOT_URL'] === 'http://localhost:4200'\n\t\t\t) {\n\t\t\t\tMonitorCPUs.create({\n\t\t\t\t\t_id: objectIdHexString(),\n\t\t\t\t\tmetadata: {\n\t\t\t\t\t\tinstance: this._instanceHostname,\n\t\t\t\t\t\tclient: ResolveIOServer.getServerConfig()['CLIENT_NAME']\n\t\t\t\t\t},\n\t\t\t\t\tdate: now,\n\t\t\t\t\tapp: percentageCPU,\n\t\t\t\t\tsystem: os.loadavg()[0]\n\t\t\t\t});\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthis.pushMonitorData({\n\t\t\t\t\ttype: 'monitor-cpu',\n\t\t\t\t\tdata: {\n\t\t\t\t\t\tmetadata: {\n\t\t\t\t\t\t\tinstance: this._instanceHostname,\n\t\t\t\t\t\t\tclient: ResolveIOServer.getServerConfig()['CLIENT_NAME']\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdate: now,\n\t\t\t\t\t\tapp: percentageCPU,\n\t\t\t\t\t\tsystem: os.loadavg()[0]\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tlastCPU = endMeasure;\n\n\t\t\tconst memUsage = process.memoryUsage();\n\n\t\t\tif (\n\t\t\t\tResolveIOServer.getServerConfig()['ROOT_URL'] === 'https://resolveio.com'\n\t\t\t|| ResolveIOServer.getServerConfig()['ROOT_URL'] === 'http://localhost:4200'\n\t\t\t) {\n\t\t\t\tMonitorMemorys.create({\n\t\t\t\t\t_id: objectIdHexString(),\n\t\t\t\t\tmetadata: {\n\t\t\t\t\t\tinstance: this._instanceHostname,\n\t\t\t\t\t\tclient: ResolveIOServer.getServerConfig()['CLIENT_NAME']\n\t\t\t\t\t},\n\t\t\t\t\tdate: now,\n\t\t\t\t\tphysical_total: memUsage.heapTotal,\n\t\t\t\t\tphysical_used: memUsage.heapUsed,\n\t\t\t\t\tphysical_free: os.freemem(),\n\t\t\t\t\tvirtual: memUsage.rss,\n\t\t\t\t\tprivate: memUsage.external,\n\t\t\t\t\tphysical: os.totalmem()\n\t\t\t\t});\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthis.pushMonitorData({\n\t\t\t\t\ttype: 'monitor-memory',\n\t\t\t\t\tdata: {\n\t\t\t\t\t\tmetadata: {\n\t\t\t\t\t\t\tinstance: this._instanceHostname,\n\t\t\t\t\t\t\tclient: ResolveIOServer.getServerConfig()['CLIENT_NAME']\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdate: now,\n\t\t\t\t\t\tphysical_total: memUsage.heapTotal,\n\t\t\t\t\t\tphysical_used: memUsage.heapUsed,\n\t\t\t\t\t\tphysical_free: os.freemem(),\n\t\t\t\t\t\tvirtual: memUsage.rss,\n\t\t\t\t\t\tprivate: memUsage.external,\n\t\t\t\t\t\tphysical: os.totalmem(),\n\t\t\t\t\t\ttype: 'memory'\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}, 3000);\n\t}\n\n\taddMongoTracker(data: MongoMonitorModel) {\n\t\tif (\n\t\t\tResolveIOServer.getServerConfig()['ROOT_URL'] === 'https://resolveio.com'\n\t\t\t|| ResolveIOServer.getServerConfig()['ROOT_URL'] === 'http://localhost:4200'\n\t\t) {\n\t\t\tif (!data.collection.startsWith('monitor-')) {\n\t\t\t\tMonitorMongos.create({\n\t\t\t\t\t_id: objectIdHexString(),\n\t\t\t\t\tmetadata: {\n\t\t\t\t\t\tinstance: this._instanceHostname,\n\t\t\t\t\t\tclient: ResolveIOServer.getServerConfig()['CLIENT_NAME']\n\t\t\t\t\t},\n\t\t\t\t\tdate: new Date(data.date),\n\t\t\t\t\tmethod: data.method,\n\t\t\t\t\tdoc_collection: data.collection,\n\t\t\t\t\tduration: data.duration,\n\t\t\t\t\tquery: Buffer.byteLength(data.query, 'utf8') < 15800000\n\t\t\t\t\t\t? data.query\n\t\t\t\t\t\t: 'Too Big'\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tif (this._instanceHostname) {\n\t\t\t\tthis.pushMonitorData({\n\t\t\t\t\ttype: 'monitor-mongo',\n\t\t\t\t\tdata: {\n\t\t\t\t\t\tmetadata: {\n\t\t\t\t\t\t\tinstance: this._instanceHostname,\n\t\t\t\t\t\t\tclient: ResolveIOServer.getServerConfig()['CLIENT_NAME']\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdate: new Date(data.date),\n\t\t\t\t\t\tmethod: data.method,\n\t\t\t\t\t\tdoc_collection: data.collection,\n\t\t\t\t\t\tduration: data.duration,\n\t\t\t\t\t\tquery: Buffer.byteLength(data.query, 'utf8') < 15800000\n\t\t\t\t\t\t\t? data.query\n\t\t\t\t\t\t\t: 'Too Big'\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\taddFunctionTracker(data: MonitorFunction) {\n\t\tif (\n\t\t\tResolveIOServer.getServerConfig()['ROOT_URL'] === 'https://resolveio.com'\n\t\t\t|| ResolveIOServer.getServerConfig()['ROOT_URL'] === 'http://localhost:4200'\n\t\t) {\n\t\t\tMonitorFunctions.create({\n\t\t\t\t_id: objectIdHexString(),\n\t\t\t\tmetadata: {\n\t\t\t\t\tinstance: this._instanceHostname,\n\t\t\t\t\tclient: ResolveIOServer.getServerConfig()['CLIENT_NAME']\n\t\t\t\t},\n\t\t\t\tdate: new Date(data.startTime),\n\t\t\t\ttype: data.functionType,\n\t\t\t\tname: data.functionName,\n\t\t\t\tuser: data.user,\n\t\t\t\tduration: data.duration,\n\t\t\t\tdata: Buffer.byteLength(data.data, 'utf8') < 15800000\n\t\t\t\t\t? data.data\n\t\t\t\t\t: 'Too Big'\n\t\t\t});\n\t\t}\n\t\telse {\n\t\t\tif (this._instanceHostname) {\n\t\t\t\tthis.pushMonitorData({\n\t\t\t\t\ttype: 'monitor-function',\n\t\t\t\t\tdata: {\n\t\t\t\t\t\tmetadata: {\n\t\t\t\t\t\t\tinstance: this._instanceHostname,\n\t\t\t\t\t\t\tclient: ResolveIOServer.getServerConfig()['CLIENT_NAME']\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdate: new Date(data.startTime),\n\t\t\t\t\t\ttype: data.functionType,\n\t\t\t\t\t\tname: data.functionName,\n\t\t\t\t\t\tuser: data.user,\n\t\t\t\t\t\tduration: data.duration,\n\t\t\t\t\t\tdata: Buffer.byteLength(data.data, 'utf8') < 15800000\n\t\t\t\t\t\t\t? data.data\n\t\t\t\t\t\t\t: 'Too Big'\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate pushMonitorData(data: LocalLogModel) {\n\t\tthis._monitorData.push(data);\n\n\t\t// If data is huge, flush immediately to file\n\t\tif (this.estimateBatchSize() >= MAX_BATCH_SIZE) {\n\t\t\tthis.flushMonitorData();\n\t\t}\n\t}\n\n\tprivate estimateBatchSize(): number {\n\t\treturn this._monitorData.reduce((total, item) => {\n\t\t\treturn total + Buffer.byteLength(JSON.stringify(item));\n\t\t}, 0);\n\t}\n\n\tsetupEventLoop() {\n\t\t// Flush every 2.5 seconds\n\t\tsetInterval(() => {\n\t\t\tif (this._monitorData.length > 0) {\n\t\t\t\tthis.flushMonitorData();\n\t\t\t}\n\t\t}, 2500);\n\t}\n\n\tprivate flushMonitorData() {\n\t\tconst batch = [];\n\t\tlet batchSize = 0;\n\n\t\twhile (this._monitorData.length > 0 && batchSize < MAX_BATCH_SIZE) {\n\t\t\tconst item = this._monitorData.shift();\n\t\t\tconst itemSize = Buffer.byteLength(JSON.stringify(item));\n\n\t\t\tif ((batchSize + itemSize) > MAX_BATCH_SIZE && batch.length > 0) {\n\t\t\t\t// put the item back for next round\n\t\t\t\tthis._monitorData.unshift(item);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tbatch.push(item);\n\t\t\tbatchSize += itemSize;\n\t\t}\n\n\t\ttry {\n\t\t\t// Now, instead of calling an external HTTP endpoint, we write the batch to disk:\n\t\t\tResolveIOServer.getLocalLogManager().writeLogs(batch);\n\t\t}\n\t\tcatch (error) {\n\t\t\tconsole.error(new Date(), 'MonitorManager', 'Failed to flush monitor data to file:', error);\n\t\t}\n\t}\n}\n\nexport interface MongoMonitorModel {\n\tdate: Date;\n\tmethod: string;\n\tcollection: string;\n\tduration: number;\n\tquery: string;\n}\n\nexport class MonitorMongo {\n\tprivate _startTime = 0;\n\tprivate _method = '';\n\tprivate _collection = '';\n\tprivate _query = '';\n\n\tconstructor(method: string, collection: string, query: string) {\n\t\tthis._startTime = Date.now();\n\t\tthis._method = method;\n\t\tthis._collection = collection;\n\t\tthis._query = query;\n\t}\n\n\tpublic finish() {\n\t\tlet endTime = Date.now();\n\n\t\tlet mongoMonitor: MongoMonitorModel = {\n\t\t\tdate: new Date(endTime),\n\t\t\tmethod: this._method,\n\t\t\tcollection: this._collection,\n\t\t\tquery: this._query,\n\t\t\tduration: endTime - this._startTime\n\t\t};\n\n\t\tResolveIOServer.getMainServer().getMonitorManager().addMongoTracker(mongoMonitor);\n\t}\n}\n\nexport class MonitorManagerFunction {\n\tprivate _functionCnt = 0;\n\tprivate _functions: MonitorFunction[] = [];\n\tprivate _functionLastCompletedWS: { [id_socket: string]: MonitorFunction; } = {};\n\tprivate _functionLastCompleted: MonitorFunction;\n\n\tconstructor() {}\n\n\tstartMonitorFunction(\n\t\tfunctionType: MonitorFunctionType,\n\t\tfunctionName: string,\n\t\tuser: string,\n\t\tid_socket: string,\n\t\tdata: any\n\t) {\n\t\tlet newMonitorFunction = new MonitorFunction(\n\t\t\tthis._functionCnt++,\n\t\t\tfunctionType,\n\t\t\tfunctionName,\n\t\t\tuser,\n\t\t\tid_socket,\n\t\t\tdata\n\t\t);\n\n\t\tthis._functions.push(newMonitorFunction);\n\t\treturn newMonitorFunction.id;\n\t}\n\n\tfinishMonitorFunction(id: number) {\n\t\tlet monitor = this._functions.find(a => a.id === id);\n\n\t\tif (monitor) {\n\t\t\tmonitor.finish();\n\t\t\tthis._functionLastCompleted = monitor;\n\t\t\tthis._functionLastCompletedWS[monitor.id_socket] = monitor;\n\t\t\tthis._functions.splice(\n\t\t\t\tthis._functions.map(a => a.id).indexOf(id),\n\t\t\t\t1\n\t\t\t);\n\t\t}\n\t}\n\n\tgetActiveMonitorFunctions() {\n\t\treturn this._functions;\n\t}\n\n\tgetLastCompletedMonitorFunction() {\n\t\treturn this._functionLastCompleted;\n\t}\n\n\tgetLastCompletedMonitorFunctionWS() {\n\t\treturn this._functionLastCompletedWS;\n\t}\n}\n\nexport type MonitorFunctionType =\n\t'Cron Method'\n\t| 'Method'\n\t| 'User Specific Publication'\n\t| 'Publication';\n\nexport class MonitorFunction {\n\tprivate _timer: NodeJS.Timeout = null;\n\tpublic duration = 0;\n\tpublic functionType: MonitorFunctionType;\n\tpublic functionName: string;\n\tpublic user: string;\n\tpublic data: any;\n\tpublic startTime: Date = null;\n\tpublic endTime: Date = null;\n\tpublic lastTime: Date = null;\n\tpublic id_socket = '';\n\tpublic id = 0;\n\n\tconstructor(\n\t\tid: number,\n\t\tfunctionType: MonitorFunctionType,\n\t\tfunctionName: string,\n\t\tuser: string,\n\t\tid_socket: string,\n\t\tdata: any\n\t) {\n\t\tthis.id = id;\n\t\tthis.startTime = new Date();\n\t\tthis.functionType = functionType;\n\t\tthis.functionName = functionName;\n\t\tthis.user = user;\n\t\tthis.id_socket = id_socket;\n\t\tthis.data = data;\n\t\tthis.lastTime = new Date();\n\n\t\tthis._timer = setInterval(() => {\n\t\t\tlet diff = Date.now() - this.lastTime.getTime();\n\n\t\t\tif (diff > this.duration) {\n\t\t\t\tthis.duration = diff;\n\t\t\t}\n\n\t\t\tthis.lastTime = new Date();\n\t\t}, 1000);\n\t}\n\n\tpublic finish() {\n\t\tif (this._timer) {\n\t\t\tclearInterval(this._timer);\n\t\t\tthis._timer = null;\n\t\t}\n\n\t\tthis.endTime = new Date();\n\n\t\tif (this.duration >= 5000) {\n\t\t\t// Optional slow function logging or email\n\t\t}\n\n\t\tResolveIOServer.getMainServer().getMonitorManager().addFunctionTracker(this);\n\t}\n}"]}
|
|
1
|
+
{"version":3,"sources":["../../src/managers/monitor.manager.ts"],"names":["axios_1","require","monitor_cpu_collection_1","monitor_memory_collection_1","monitor_mongo_collection_1","resolveio_server_app_1","common_1","monitor_function_collection_1","os","MAX_BATCH_SIZE","MonitorManager","this","_instanceHostname","_monitorData","hostname","replace","setupIntervals","setupEventLoop","prototype","cpuAverage","totalIdle","totalTick","cpus","i","len","length","type","cpu","times","idle","total","ResolveIOServer","getServerConfig","default","get","instanceId_1","_a","sent","setInterval","__awaiter","_this","post","id_aws_instance","data","version","process","env","APP_VERSION","toString","version_key","APP_VERSION_KEY","lastCPU","now","Date","endMeasure","percentageCPU","memUsage","MonitorCPUs","create","_id","objectIdHexString","metadata","instance","client","date","app","system","loadavg","pushMonitorData","memoryUsage","MonitorMemorys","physical_total","heapTotal","physical_used","heapUsed","physical_free","freemem","virtual","rss","private","external","physical","totalmem","addMongoTracker","collection","startsWith","MonitorMongos","method","doc_collection","duration","query","Buffer","byteLength","addFunctionTracker","JSON","stringify","MonitorFunctions","startTime","functionType","name","functionName","user","push","estimateBatchSize","flushMonitorData","reduce","item","batch","batchSize","shift","itemSize","unshift","getLocalLogManager","writeLogs","error","console","MonitorMongo","exports","_startTime","_method","_collection","_query","finish","endTime","mongoMonitor","getMainServer","getMonitorManager","MonitorManagerFunction","_functionCnt","_functions","_functionLastCompletedWS","startMonitorFunction","id_socket","newMonitorFunction","MonitorFunction","id","finishMonitorFunction","monitor","find","a","_functionLastCompleted","splice","map","indexOf","getActiveMonitorFunctions","getLastCompletedMonitorFunction","getLastCompletedMonitorFunctionWS","_timer","lastTime","diff","getTime","clearInterval"],"mappings":"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","file":"monitor.manager.js","sourcesContent":["import axios from 'axios';\nimport { MonitorCPUs } from '../collections/monitor-cpu.collection';\nimport { MonitorMemorys } from '../collections/monitor-memory.collection';\nimport { MonitorMongos } from '../collections/monitor-mongo.collection';\nimport { ResolveIOServer } from '../resolveio-server-app';\nimport { objectIdHexString } from '../util/common';\nimport { LocalLogModel } from './local-log.manager';\nimport { MonitorFunctions } from '../collections/monitor-function.collection';\n\nconst os = require('os');\nconst MAX_BATCH_SIZE = 8 * 1024 * 1024; // 8MB max for safety\n\nexport class MonitorManager {\n\tprivate _instanceHostname = '';\n\tprivate _monitorData: LocalLogModel[] = [];\n\n\tconstructor() {\n\t\tthis._instanceHostname = os.hostname().replace(/\\./g, '-');\n\n\t\tthis.setupIntervals();\n\t\tthis.setupEventLoop();\n\t}\n\n\tcpuAverage() {\n\t\tvar totalIdle = 0, totalTick = 0;\n\t\tvar cpus = os.cpus();\n\n\t\tfor (var i = 0, len = cpus.length; i < len; i++) {\n\t\t\tvar cpu = cpus[i];\n\n\t\t\tfor (let type in cpu.times) {\n\t\t\t\ttotalTick += cpu.times[type];\n\t\t\t}\n\t\t\ttotalIdle += cpu.times.idle;\n\t\t}\n\n\t\treturn {\n\t\t\tidle: totalIdle / cpus.length,\n\t\t\ttotal: totalTick / cpus.length\n\t\t};\n\t}\n\n\tasync setupIntervals() {\n\t\t// Example: If not on production or localhost, do a health check\n\t\tif (\n\t\t\tResolveIOServer.getServerConfig()['ROOT_URL'] !== 'https://resolveio.com'\n\t\t&& ResolveIOServer.getServerConfig()['ROOT_URL'] !== 'http://localhost:4200'\n\t\t) {\n\t\t\ttry {\n\t\t\t\tlet instanceId = await axios.get('http://169.254.169.254/latest/meta-data/instance-id');\n\n\t\t\t\tsetInterval(async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait axios.post('https://backend.resolveio.com/api/health', {\n\t\t\t\t\t\t\ttype: 'application',\n\t\t\t\t\t\t\tid_aws_instance: instanceId.data,\n\t\t\t\t\t\t\tversion: typeof process.env.APP_VERSION === 'number'\n\t\t\t\t\t\t\t\t? (<any>process.env.APP_VERSION).toString()\n\t\t\t\t\t\t\t\t: process.env.APP_VERSION,\n\t\t\t\t\t\t\tversion_key: process.env.APP_VERSION_KEY\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tcatch(e) {}\n\t\t\t\t}, 10000);\n\t\t\t}\n\t\t\tcatch(errHealth) {}\n\t\t}\n\n\t\tlet lastCPU = this.cpuAverage();\n\n\t\tsetInterval(() => {\n\t\t\tlet now = new Date();\n\t\t\tvar endMeasure = this.cpuAverage();\n\t\t\tvar idleDifference = endMeasure.idle - lastCPU.idle;\n\t\t\tvar totalDifference = endMeasure.total - lastCPU.total;\n\t\t\tvar percentageCPU = 1 - idleDifference / totalDifference;\n\n\t\t\t// Original local code\n\t\t\tif (\n\t\t\t\tResolveIOServer.getServerConfig()['ROOT_URL'] === 'https://resolveio.com'\n\t\t\t|| ResolveIOServer.getServerConfig()['ROOT_URL'] === 'http://localhost:4200'\n\t\t\t) {\n\t\t\t\tMonitorCPUs.create({\n\t\t\t\t\t_id: objectIdHexString(),\n\t\t\t\t\tmetadata: {\n\t\t\t\t\t\tinstance: this._instanceHostname,\n\t\t\t\t\t\tclient: ResolveIOServer.getServerConfig()['CLIENT_NAME']\n\t\t\t\t\t},\n\t\t\t\t\tdate: now,\n\t\t\t\t\tapp: percentageCPU,\n\t\t\t\t\tsystem: os.loadavg()[0]\n\t\t\t\t});\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthis.pushMonitorData({\n\t\t\t\t\ttype: 'monitor-cpu',\n\t\t\t\t\tdata: {\n\t\t\t\t\t\tmetadata: {\n\t\t\t\t\t\t\tinstance: this._instanceHostname,\n\t\t\t\t\t\t\tclient: ResolveIOServer.getServerConfig()['CLIENT_NAME']\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdate: now,\n\t\t\t\t\t\tapp: percentageCPU,\n\t\t\t\t\t\tsystem: os.loadavg()[0]\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tlastCPU = endMeasure;\n\n\t\t\tconst memUsage = process.memoryUsage();\n\n\t\t\tif (\n\t\t\t\tResolveIOServer.getServerConfig()['ROOT_URL'] === 'https://resolveio.com'\n\t\t\t|| ResolveIOServer.getServerConfig()['ROOT_URL'] === 'http://localhost:4200'\n\t\t\t) {\n\t\t\t\tMonitorMemorys.create({\n\t\t\t\t\t_id: objectIdHexString(),\n\t\t\t\t\tmetadata: {\n\t\t\t\t\t\tinstance: this._instanceHostname,\n\t\t\t\t\t\tclient: ResolveIOServer.getServerConfig()['CLIENT_NAME']\n\t\t\t\t\t},\n\t\t\t\t\tdate: now,\n\t\t\t\t\tphysical_total: memUsage.heapTotal,\n\t\t\t\t\tphysical_used: memUsage.heapUsed,\n\t\t\t\t\tphysical_free: os.freemem(),\n\t\t\t\t\tvirtual: memUsage.rss,\n\t\t\t\t\tprivate: memUsage.external,\n\t\t\t\t\tphysical: os.totalmem()\n\t\t\t\t});\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthis.pushMonitorData({\n\t\t\t\t\ttype: 'monitor-memory',\n\t\t\t\t\tdata: {\n\t\t\t\t\t\tmetadata: {\n\t\t\t\t\t\t\tinstance: this._instanceHostname,\n\t\t\t\t\t\t\tclient: ResolveIOServer.getServerConfig()['CLIENT_NAME']\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdate: now,\n\t\t\t\t\t\tphysical_total: memUsage.heapTotal,\n\t\t\t\t\t\tphysical_used: memUsage.heapUsed,\n\t\t\t\t\t\tphysical_free: os.freemem(),\n\t\t\t\t\t\tvirtual: memUsage.rss,\n\t\t\t\t\t\tprivate: memUsage.external,\n\t\t\t\t\t\tphysical: os.totalmem(),\n\t\t\t\t\t\ttype: 'memory'\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}, 3000);\n\t}\n\n\taddMongoTracker(data: MongoMonitorModel) {\n\t\tif (\n\t\t\tResolveIOServer.getServerConfig()['ROOT_URL'] === 'https://resolveio.com'\n\t\t\t|| ResolveIOServer.getServerConfig()['ROOT_URL'] === 'http://localhost:4200'\n\t\t) {\n\t\t\tif (!data.collection.startsWith('monitor-')) {\n\t\t\t\tMonitorMongos.create({\n\t\t\t\t\t_id: objectIdHexString(),\n\t\t\t\t\tmetadata: {\n\t\t\t\t\t\tinstance: this._instanceHostname,\n\t\t\t\t\t\tclient: ResolveIOServer.getServerConfig()['CLIENT_NAME']\n\t\t\t\t\t},\n\t\t\t\t\tdate: new Date(data.date),\n\t\t\t\t\tmethod: data.method,\n\t\t\t\t\tdoc_collection: data.collection,\n\t\t\t\t\tduration: data.duration,\n\t\t\t\t\tquery: Buffer.byteLength(data.query, 'utf8') < 15800000\n\t\t\t\t\t\t? data.query\n\t\t\t\t\t\t: 'Too Big'\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tif (this._instanceHostname) {\n\t\t\t\tthis.pushMonitorData({\n\t\t\t\t\ttype: 'monitor-mongo',\n\t\t\t\t\tdata: {\n\t\t\t\t\t\tmetadata: {\n\t\t\t\t\t\t\tinstance: this._instanceHostname,\n\t\t\t\t\t\t\tclient: ResolveIOServer.getServerConfig()['CLIENT_NAME']\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdate: new Date(data.date),\n\t\t\t\t\t\tmethod: data.method,\n\t\t\t\t\t\tdoc_collection: data.collection,\n\t\t\t\t\t\tduration: data.duration,\n\t\t\t\t\t\tquery: Buffer.byteLength(data.query, 'utf8') < 15800000\n\t\t\t\t\t\t\t? data.query\n\t\t\t\t\t\t\t: 'Too Big'\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\taddFunctionTracker(data: MonitorFunction) {\n\t\tif (typeof(data.data) !== 'string') {\n\t\t\tdata.data = JSON.stringify(data.data);\n\t\t}\n\n\t\tif (\n\t\t\tResolveIOServer.getServerConfig()['ROOT_URL'] === 'https://resolveio.com'\n\t\t\t|| ResolveIOServer.getServerConfig()['ROOT_URL'] === 'http://localhost:4200'\n\t\t) {\n\t\t\tMonitorFunctions.create({\n\t\t\t\t_id: objectIdHexString(),\n\t\t\t\tmetadata: {\n\t\t\t\t\tinstance: this._instanceHostname,\n\t\t\t\t\tclient: ResolveIOServer.getServerConfig()['CLIENT_NAME']\n\t\t\t\t},\n\t\t\t\tdate: new Date(data.startTime),\n\t\t\t\ttype: data.functionType,\n\t\t\t\tname: data.functionName,\n\t\t\t\tuser: data.user,\n\t\t\t\tduration: data.duration,\n\t\t\t\tdata: Buffer.byteLength(data.data, 'utf8') < 15800000\n\t\t\t\t\t? data.data\n\t\t\t\t\t: 'Too Big'\n\t\t\t});\n\t\t}\n\t\telse {\n\t\t\tif (this._instanceHostname) {\n\t\t\t\tthis.pushMonitorData({\n\t\t\t\t\ttype: 'monitor-function',\n\t\t\t\t\tdata: {\n\t\t\t\t\t\tmetadata: {\n\t\t\t\t\t\t\tinstance: this._instanceHostname,\n\t\t\t\t\t\t\tclient: ResolveIOServer.getServerConfig()['CLIENT_NAME']\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdate: new Date(data.startTime),\n\t\t\t\t\t\ttype: data.functionType,\n\t\t\t\t\t\tname: data.functionName,\n\t\t\t\t\t\tuser: data.user,\n\t\t\t\t\t\tduration: data.duration,\n\t\t\t\t\t\tdata: Buffer.byteLength(data.data, 'utf8') < 15800000\n\t\t\t\t\t\t\t? data.data\n\t\t\t\t\t\t\t: 'Too Big'\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate pushMonitorData(data: LocalLogModel) {\n\t\tthis._monitorData.push(data);\n\n\t\t// If data is huge, flush immediately to file\n\t\tif (this.estimateBatchSize() >= MAX_BATCH_SIZE) {\n\t\t\tthis.flushMonitorData();\n\t\t}\n\t}\n\n\tprivate estimateBatchSize(): number {\n\t\treturn this._monitorData.reduce((total, item) => {\n\t\t\treturn total + Buffer.byteLength(JSON.stringify(item));\n\t\t}, 0);\n\t}\n\n\tsetupEventLoop() {\n\t\t// Flush every 2.5 seconds\n\t\tsetInterval(() => {\n\t\t\tif (this._monitorData.length > 0) {\n\t\t\t\tthis.flushMonitorData();\n\t\t\t}\n\t\t}, 2500);\n\t}\n\n\tprivate flushMonitorData() {\n\t\tconst batch = [];\n\t\tlet batchSize = 0;\n\n\t\twhile (this._monitorData.length > 0 && batchSize < MAX_BATCH_SIZE) {\n\t\t\tconst item = this._monitorData.shift();\n\t\t\tconst itemSize = Buffer.byteLength(JSON.stringify(item));\n\n\t\t\tif ((batchSize + itemSize) > MAX_BATCH_SIZE && batch.length > 0) {\n\t\t\t\t// put the item back for next round\n\t\t\t\tthis._monitorData.unshift(item);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tbatch.push(item);\n\t\t\tbatchSize += itemSize;\n\t\t}\n\n\t\ttry {\n\t\t\t// Now, instead of calling an external HTTP endpoint, we write the batch to disk:\n\t\t\tResolveIOServer.getLocalLogManager().writeLogs(batch);\n\t\t}\n\t\tcatch (error) {\n\t\t\tconsole.error(new Date(), 'MonitorManager', 'Failed to flush monitor data to file:', error);\n\t\t}\n\t}\n}\n\nexport interface MongoMonitorModel {\n\tdate: Date;\n\tmethod: string;\n\tcollection: string;\n\tduration: number;\n\tquery: string;\n}\n\nexport class MonitorMongo {\n\tprivate _startTime = 0;\n\tprivate _method = '';\n\tprivate _collection = '';\n\tprivate _query = '';\n\n\tconstructor(method: string, collection: string, query: string) {\n\t\tthis._startTime = Date.now();\n\t\tthis._method = method;\n\t\tthis._collection = collection;\n\t\tthis._query = query;\n\t}\n\n\tpublic finish() {\n\t\tlet endTime = Date.now();\n\n\t\tlet mongoMonitor: MongoMonitorModel = {\n\t\t\tdate: new Date(endTime),\n\t\t\tmethod: this._method,\n\t\t\tcollection: this._collection,\n\t\t\tquery: this._query,\n\t\t\tduration: endTime - this._startTime\n\t\t};\n\n\t\tResolveIOServer.getMainServer().getMonitorManager().addMongoTracker(mongoMonitor);\n\t}\n}\n\nexport class MonitorManagerFunction {\n\tprivate _functionCnt = 0;\n\tprivate _functions: MonitorFunction[] = [];\n\tprivate _functionLastCompletedWS: { [id_socket: string]: MonitorFunction; } = {};\n\tprivate _functionLastCompleted: MonitorFunction;\n\n\tconstructor() {}\n\n\tstartMonitorFunction(\n\t\tfunctionType: MonitorFunctionType,\n\t\tfunctionName: string,\n\t\tuser: string,\n\t\tid_socket: string,\n\t\tdata: any\n\t) {\n\t\tlet newMonitorFunction = new MonitorFunction(\n\t\t\tthis._functionCnt++,\n\t\t\tfunctionType,\n\t\t\tfunctionName,\n\t\t\tuser,\n\t\t\tid_socket,\n\t\t\tdata\n\t\t);\n\n\t\tthis._functions.push(newMonitorFunction);\n\t\treturn newMonitorFunction.id;\n\t}\n\n\tfinishMonitorFunction(id: number) {\n\t\tlet monitor = this._functions.find(a => a.id === id);\n\n\t\tif (monitor) {\n\t\t\tmonitor.finish();\n\t\t\tthis._functionLastCompleted = monitor;\n\t\t\tthis._functionLastCompletedWS[monitor.id_socket] = monitor;\n\t\t\tthis._functions.splice(\n\t\t\t\tthis._functions.map(a => a.id).indexOf(id),\n\t\t\t\t1\n\t\t\t);\n\t\t}\n\t}\n\n\tgetActiveMonitorFunctions() {\n\t\treturn this._functions;\n\t}\n\n\tgetLastCompletedMonitorFunction() {\n\t\treturn this._functionLastCompleted;\n\t}\n\n\tgetLastCompletedMonitorFunctionWS() {\n\t\treturn this._functionLastCompletedWS;\n\t}\n}\n\nexport type MonitorFunctionType =\n\t'Cron Method'\n\t| 'Method'\n\t| 'User Specific Publication'\n\t| 'Publication';\n\nexport class MonitorFunction {\n\tprivate _timer: NodeJS.Timeout = null;\n\tpublic duration = 0;\n\tpublic functionType: MonitorFunctionType;\n\tpublic functionName: string;\n\tpublic user: string;\n\tpublic data: any;\n\tpublic startTime: Date = null;\n\tpublic endTime: Date = null;\n\tpublic lastTime: Date = null;\n\tpublic id_socket = '';\n\tpublic id = 0;\n\n\tconstructor(\n\t\tid: number,\n\t\tfunctionType: MonitorFunctionType,\n\t\tfunctionName: string,\n\t\tuser: string,\n\t\tid_socket: string,\n\t\tdata: any\n\t) {\n\t\tthis.id = id;\n\t\tthis.startTime = new Date();\n\t\tthis.functionType = functionType;\n\t\tthis.functionName = functionName;\n\t\tthis.user = user;\n\t\tthis.id_socket = id_socket;\n\t\tthis.data = data;\n\t\tthis.lastTime = new Date();\n\n\t\tthis._timer = setInterval(() => {\n\t\t\tlet diff = Date.now() - this.lastTime.getTime();\n\n\t\t\tif (diff > this.duration) {\n\t\t\t\tthis.duration = diff;\n\t\t\t}\n\n\t\t\tthis.lastTime = new Date();\n\t\t}, 1000);\n\t}\n\n\tpublic finish() {\n\t\tif (this._timer) {\n\t\t\tclearInterval(this._timer);\n\t\t\tthis._timer = null;\n\t\t}\n\n\t\tthis.endTime = new Date();\n\n\t\tif (this.duration >= 5000) {\n\t\t\t// Optional slow function logging or email\n\t\t}\n\n\t\tResolveIOServer.getMainServer().getMonitorManager().addFunctionTracker(this);\n\t}\n}"]}
|
package/package.json
CHANGED
package/server-app.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var __awaiter=this&&this.__awaiter||function(e,o,s,n){return new(s=s||Promise)(function(t,r){function fulfilled(e){try{step(n.next(e))}catch(e){r(e)}}function rejected(e){try{step(n.throw(e))}catch(e){r(e)}}function step(e){var r;e.done?t(e.value):((r=e.value)instanceof s?r:new s(function(e){e(r)})).then(fulfilled,rejected)}step((n=n.apply(e,o||[])).next())})},__generator=this&&this.__generator||function(o,s){var n,i,a,l={label:0,sent:function(){if(1&a[0])throw a[1];return a[1]},trys:[],ops:[]},c={next:verb(0),throw:verb(1),return:verb(2)};return"function"==typeof Symbol&&(c[Symbol.iterator]=function(){return this}),c;function verb(t){return function(e){var r=[t,e];if(n)throw new TypeError("Generator is already executing.");for(;l=c&&r[c=0]?0:l;)try{if(n=1,i&&(a=2&r[0]?i.return:r[0]?i.throw||((a=i.return)&&a.call(i),0):i.next)&&!(a=a.call(i,r[1])).done)return a;switch(i=0,(r=a?[2&r[0],a.value]:r)[0]){case 0:case 1:a=r;break;case 4:return l.label++,{value:r[1],done:!1};case 5:l.label++,i=r[1],r=[0];continue;case 7:r=l.ops.pop(),l.trys.pop();continue;default:if(!(a=0<(a=l.trys).length&&a[a.length-1])&&(6===r[0]||2===r[0])){l=0;continue}if(3===r[0]&&(!a||r[1]>a[0]&&r[1]<a[3]))l.label=r[1];else if(6===r[0]&&l.label<a[1])l.label=a[1],a=r;else{if(!(a&&l.label<a[2])){a[2]&&l.ops.pop(),l.trys.pop();continue}l.label=a[2],l.ops.push(r)}}r=s.call(o,l)}catch(e){r=[6,e],i=0}finally{n=a=0}if(5&r[0])throw r[1];return{value:r[0]?r[1]:void 0,done:!0}}}},__read=this&&this.__read||function(e,r){var t="function"==typeof Symbol&&e[Symbol.iterator];if(!t)return e;var o,s,n=t.call(e),i=[];try{for(;(void 0===r||0<r--)&&!(o=n.next()).done;)i.push(o.value)}catch(e){s={error:e}}finally{try{o&&!o.done&&(t=n.return)&&t.call(n)}finally{if(s)throw s.error}}return i},__spreadArray=this&&this.__spreadArray||function(e,r,t){if(t||2===arguments.length)for(var o,s=0,n=r.length;s<n;s++)!o&&s in r||((o=o||Array.prototype.slice.call(r,0,s))[s]=r[s]);return e.concat(o||Array.prototype.slice.call(r))},__values=this&&this.__values||function(e){var r="function"==typeof Symbol&&Symbol.iterator,t=r&&e[r],o=0;if(t)return t.call(e);if(e&&"number"==typeof e.length)return{next:function(){return{value:(e=e&&o>=e.length?void 0:e)&&e[o++],done:!e}}};throw new TypeError(r?"Object is not iterable.":"Symbol.iterator is not defined.")},http_1=(Object.defineProperty(exports,"__esModule",{value:!0}),exports.ResolveIOMainServer=void 0,require("http")),express=require("express"),bodyParser=require("body-parser"),xmlParser=require("express-xml-bodyparser"),WebSocket=require("ws"),jwt=require("jsonwebtoken"),moment=require("moment-timezone"),common_1=require("./util/common"),cron_manager_1=require("./managers/cron.manager"),method_manager_1=require("./managers/method.manager"),subscription_manager_1=require("./managers/subscription.manager"),monitor_manager_1=require("./managers/monitor.manager"),log_collection_1=require("./collections/log.collection"),user_collection_1=require("./collections/user.collection"),home_1=require("./http/home"),auth_1=require("./http/auth"),health_1=require("./http/health"),mongodb_1=require("mongodb"),websocket_manager_1=require("./managers/websocket.manager"),resolveio_server_app_1=require("./resolveio-server-app"),ResolveIOMainServer=function(){function ResolveIOMainServer(){this._offlineUpdates=[],this.sesMail=!1,this.standardProgram=!1,this.publicProgram=!1,this._rebootFlag=!1,this.LOGGER="ERROR",this._clientRoutes=[],this._lastErrorMsg=null,this._debugMsgRecv=0,this._debugMsgQueue=0,this._isWorkersEnabled=!1,this._isWorkerInstance=!1,this._safeShutdown=!1,this._workers=[],this._taskQueue=[],this._inFlightRequests={},this._serverStartTime=new Date,this._lastErrorMsg=null,this._monitorManager=new monitor_manager_1.MonitorManager,this._monitorManagerFunction=new monitor_manager_1.MonitorManagerFunction}return ResolveIOMainServer.prototype.initServerApp=function(){var e=this;this._isWorkersEnabled="true"===process.env.IS_WORKERS_ENABLED,this._isWorkerInstance="true"===process.env.IS_WORKER_INSTANCE,setInterval(function(){e._subscriptionManager&&e._subscriptionManager.getEnableDebug()&&(console.log(new Date,"Server App","Msg Recv Hits",e._debugMsgRecv),console.log(new Date,"Server App","Msg Queue Hits",e._debugMsgQueue)),e._debugMsgQueue=0,e._debugMsgRecv=0},6e4),process.on("unhandledRejection",function(o,s){return __awaiter(e,void 0,void 0,function(){var r,t=this;return __generator(this,function(e){switch(e.label){case 0:return o&&"MongoError"===o.name&&48===o.code?[2]:(console.error(new Date,"Unhandled Rejection at Promise",[o,s]),r=moment().diff(this._serverStartTime,"seconds"),o&&("MongoNetworkTimeoutError"===o.name||o instanceof mongodb_1.MongoNetworkTimeoutError)?60<r&&!this._lastErrorMsg?(this._lastErrorMsg=new Date,setTimeout(function(){t._lastErrorMsg=null},6e4),[4,this._methodManager.sendEmail("dev@resolveio.com","SERVER - MongoNetworkTimeoutError - Quitting NodeJS - "+resolveio_server_app_1.ResolveIOServer.getServerConfig().CLIENT_NAME,JSON.stringify({name:o.name,message:o.message,stack:o.stack},null,2))]):[3,2]:[3,3]);case 1:e.sent(),process.exit(1),e.label=2;case 2:return[3,10];case 3:return o&&"MongoError"===o.name&&"not master"===o.message?60<r&&!this._lastErrorMsg?(this._lastErrorMsg=new Date,setTimeout(function(){t._lastErrorMsg=null},6e4),[4,this._methodManager.sendEmail("dev@resolveio.com","SERVER - Unhandled Rejection - Quitting NodeJS - "+resolveio_server_app_1.ResolveIOServer.getServerConfig().CLIENT_NAME,JSON.stringify([o.name,o.message,o.stack],null,2))]):[3,5]:[3,6];case 4:e.sent(),e.label=5;case 5:return process.exit(1),[3,10];case 6:return o&&"MongoError"===o.name&&"not master and slaveOk=false"===o.message?60<r&&!this._lastErrorMsg?(this._lastErrorMsg=new Date,setTimeout(function(){t._lastErrorMsg=null},6e4),[4,this._methodManager.sendEmail("dev@resolveio.com","SERVER - Unhandled Rejection - Quitting NodeJS - "+resolveio_server_app_1.ResolveIOServer.getServerConfig().CLIENT_NAME,JSON.stringify([o.name,o.message,o.stack],null,2))]):[3,8]:[3,9];case 7:e.sent(),e.label=8;case 8:return process.exit(1),[3,10];case 9:o&&"StatusError"!==o.name&&""!==o.message&&60<r&&!this._lastErrorMsg&&(this._lastErrorMsg=new Date,setTimeout(function(){t._lastErrorMsg=null},6e4),this._methodManager.sendEmail("dev@resolveio.com","SERVER - Unhandled Rejection - "+resolveio_server_app_1.ResolveIOServer.getServerConfig().CLIENT_NAME,JSON.stringify([o.name,o.message,o.stack],null,2))),e.label=10;case 10:return[2]}})})}),process.on("uncaughtException",function(t){return __awaiter(e,void 0,void 0,function(){var r=this;return __generator(this,function(e){switch(e.label){case 0:return(console.error(t,"Uncaught Exception thrown"),60<moment().diff(this._serverStartTime,"seconds")&&!this._lastErrorMsg)?(this._lastErrorMsg=new Date,setTimeout(function(){r._lastErrorMsg=null},6e4),[4,this._methodManager.sendEmail("dev@resolveio.com","SERVER - Unhandled Exception - "+resolveio_server_app_1.ResolveIOServer.getServerConfig().CLIENT_NAME,JSON.stringify([t.name,t.message,t.stack],null,2))]):[3,2];case 1:e.sent(),e.label=2;case 2:return[2]}})})}),process.on("SIGINT",function(){e._rebootFlag=!0,e._serverHTTP&&e._serverHTTP.close(),e.safeShutdown()}),process.on("SIGTERM",function(){e._rebootFlag=!0,e._serverHTTP&&e._serverHTTP.close(),e.safeShutdown()}),process.on("SIGQUIT",function(){e._rebootFlag=!0,e._serverHTTP&&e._serverHTTP.close(),e.safeShutdown()}),"DEBUG"===this.LOGGER&&console.log("Starting ResolveIO Server"),this._isWorkersEnabled?this._isWorkerInstance?(console.log("Running as a Worker instance"),this._methodManager=new method_manager_1.MethodManager(this._monitorManagerFunction,this._isWorkersEnabled,this._isWorkerInstance),this._cronManager=new cron_manager_1.CronManager,this.startWorkerInstance()):(console.log("Running as a Server instance"),this._websocketManager=new websocket_manager_1.WebSocketManager(this),this.startServerInstance(),this._methodManager=new method_manager_1.MethodManager(this._monitorManagerFunction,this._isWorkersEnabled,this._isWorkerInstance),this._subscriptionManager=new subscription_manager_1.SubscriptionManager(this._serverWSS,resolveio_server_app_1.ResolveIOServer.getServerConfig(),this._monitorManagerFunction),this.listen()):(console.log("Running with Workers Disabled"),this._websocketManager=new websocket_manager_1.WebSocketManager(this),this.startServerInstance(),this._methodManager=new method_manager_1.MethodManager(this._monitorManagerFunction,this._isWorkersEnabled,this._isWorkerInstance),this._subscriptionManager=new subscription_manager_1.SubscriptionManager(this._serverWSS,resolveio_server_app_1.ResolveIOServer.getServerConfig(),this._monitorManagerFunction),this._cronManager=new cron_manager_1.CronManager,this.listen())},ResolveIOMainServer.prototype.startServerInstance=function(){this._app=express(),this._app.use(bodyParser.json({limit:"50mb",reviver:common_1.dateReviver})),this._app.use(bodyParser.urlencoded({limit:"50mb",extended:!0,parameterLimit:1e6})),this._app.use(xmlParser()),this._portHTTP=process.env.PORT_HTTP||resolveio_server_app_1.ResolveIOServer.getServerConfig().PORT_HTTP||8080,this._portWSS=process.env.PORT_WSS||resolveio_server_app_1.ResolveIOServer.getServerConfig().PORT_WSS||8081,"DEBUG"===this.LOGGER&&console.log("Setup ports"),this.createServer(),"DEBUG"===this.LOGGER&&console.log("Create server"),this._app.use(function(e,r,t){r.setHeader("Access-Control-Allow-Origin","*"),r.setHeader("Access-Control-Allow-Methods","GET, POST"),r.setHeader("Access-Control-Allow-Headers","X-Requested-With,content-type"),r.setHeader("Access-Control-Allow-Credentials","false"),t()}),"DEBUG"===this.LOGGER&&console.log("Setup cors"),(0,auth_1.setupAuthRoutes)(this,this._app,resolveio_server_app_1.ResolveIOServer.getServerConfig()),(0,health_1.setupHealthRoutes)(this._app,resolveio_server_app_1.ResolveIOServer.getServerConfig()),"ResolveIO"!==resolveio_server_app_1.ResolveIOServer.getServerConfig().CLIENT_NAME&&!this.standardProgram||(0,home_1.setupHomeRoutes)(this,this._app,resolveio_server_app_1.ResolveIOServer.getServerConfig()),"DEBUG"===this.LOGGER&&console.log("Setup express routes")},ResolveIOMainServer.prototype.startWorkerInstance=function(){return __awaiter(this,void 0,void 0,function(){var r,t,s=this;return __generator(this,function(e){return console.log(new Date,"Worker instance started, connecting to main server via WebSocket..."),r=resolveio_server_app_1.ResolveIOServer.getServerConfig().SERVER_URL+"/websocket?workerToken="+resolveio_server_app_1.ResolveIOServer.getServerConfig().WORKER_TOKEN,(t=function(){var o=new WebSocket(r);o.on("open",function(){console.log(new Date,"Connected to main server as worker",process.env.WORKER_INDEX,process.env.NODE_APP_INSTANCE)}),o.on("message",function(t){return __awaiter(s,void 0,void 0,function(){var r;return __generator(this,function(e){try{r=JSON.parse(t.toString(),common_1.dateReviver)}catch(e){return console.error("Worker parse error",e),[2]}return"task"===r.type&&this.handleIncomingTask(o,r),[2]})})}),o.on("close",function(){console.log(new Date,"Disconnected from main server. Reconnecting in 5s..."),setTimeout(t,5e3)}),o.on("error",function(e){console.error(new Date,"Worker WS error:",e),o.close()})})(),[2]})})},ResolveIOMainServer.prototype.handleIncomingTask=function(u,_){return __awaiter(this,void 0,void 0,function(){var r,t,o,s,n,i,a,l,c=this;return __generator(this,function(e){switch(e.label){case 0:if(r=_.taskId,t=_.method,o=_.params,s=_.userContext,!r||!t)return console.log("Invalid task message received",_),[2];n=!1,i=setTimeout(function(){n=!0,console.error("Worker timed out on task:",r),c.sendWorkerResponse(u,{type:"taskComplete",taskId:r,error:!0,message:"Task timed out"})},12e4),e.label=1;case 1:return e.trys.push([1,3,,4]),a=Object.assign({},this._methodManager,method_manager_1.MethodManager.prototype,{id_user:(null==s?void 0:s.id_user)||"",user:(null==s?void 0:s.user)||"",id_ws:(null==s?void 0:s.id_ws)||""}),[4,(l=this._methodManager.callMethod).call.apply(l,__spreadArray([a,t],__read(o),!1))];case 2:return l=e.sent(),n||(clearTimeout(i),this.sendWorkerResponse(u,{type:"taskComplete",taskId:r,error:!1,result:l})),[3,4];case 3:return a=e.sent(),n||(clearTimeout(i),console.error("Worker failed task:",r,a),this.sendWorkerResponse(u,{type:"taskComplete",taskId:r,error:!0,message:a.message||"Unknown error"})),[3,4];case 4:return[2]}})})},ResolveIOMainServer.prototype.sendWorkerResponse=function(e,r){try{e.send(JSON.stringify(r))}catch(e){console.error("Failed to send worker response:",e)}},ResolveIOMainServer.prototype.safeShutdown=function(){var e=this;this._safeShutdown||console.log(new Date,"Safe Shutdown Command Received"),this._monitorManagerFunction.getActiveMonitorFunctions().length||this._offlineUpdates.length?(this._safeShutdown||(this._safeShutdown=!0,setTimeout(function(){e._safeShutdown=!1},1e3),console.log(new Date,"Safe Exit In Progress",this._monitorManagerFunction.getActiveMonitorFunctions().length,this._offlineUpdates.length)),setImmediate(function(){e.safeShutdown()})):resolveio_server_app_1.ResolveIOServer.getMongoConnection()?resolveio_server_app_1.ResolveIOServer.getMongoConnection().close(!1).then(function(){console.log(new Date,"Safe Exit Complete, Process Exit"),process.exit(0)},function(){process.exit(1)}):process.exit(0)},ResolveIOMainServer.prototype.getIsWorkersEnabled=function(){return this._isWorkersEnabled},ResolveIOMainServer.prototype.getIsWorkerInstance=function(){return this._isWorkerInstance},ResolveIOMainServer.prototype.getWSList=function(){var r=[];return this._serverWSS.clients.forEach(function(e){r.push(e.id_socket)}),r},ResolveIOMainServer.prototype.getWSUserList=function(){var r=[];return this._serverWSS.clients.forEach(function(e){r.push(e.id_user)}),r},ResolveIOMainServer.prototype.getHTTPServer=function(){return this._serverHTTP},ResolveIOMainServer.prototype.getCronManager=function(){return this._cronManager},ResolveIOMainServer.prototype.getMethodManager=function(){return this._methodManager},ResolveIOMainServer.prototype.getSubscriptionManager=function(){return this._subscriptionManager},ResolveIOMainServer.prototype.getMonitorManager=function(){return this._monitorManager},ResolveIOMainServer.prototype.getRebootFlag=function(){return this._rebootFlag},ResolveIOMainServer.prototype.getWebSocketManager=function(){return this._websocketManager},ResolveIOMainServer.prototype.createServer=function(){var e=this;this._serverHTTP=(0,http_1.createServer)(this._app),this._serverHTTP.keepAliveTimeout=65e3,this._serverHTTP.headersTimeout=66e3,this._serverWSS=new WebSocket.Server({port:this._portWSS,verifyClient:this.publicProgram?null:function(n,i){return __awaiter(e,void 0,void 0,function(){var r,t,s=this;return __generator(this,function(e){if(this._rebootFlag)i(!1,409,"Unable To Process");else{if("DEBUG"===this.LOGGER&&console.log("Verify Client",n,i),n.req.url&&n.req.url.includes("workerToken="))return r=n.req.url.split("workerToken="),(r[1]||"")===resolveio_server_app_1.ResolveIOServer.getServerConfig().WORKER_TOKEN?i(!0):i(!1,401,"Unauthorized"),[2];r=n.req.headers["sec-websocket-protocol"].split(/,/),(n.origin===resolveio_server_app_1.ResolveIOServer.getServerConfig().ROOT_URL||n.origin===resolveio_server_app_1.ResolveIOServer.getServerConfig().SEC_ROOT_URL||n.origin===resolveio_server_app_1.ResolveIOServer.getServerConfig().RESOLVEIO_URL||n.origin===resolveio_server_app_1.ResolveIOServer.getServerConfig().RESOLVEIO_SECONDARY_URL)&&(t=r[0])?jwt.verify(t,resolveio_server_app_1.ResolveIOServer.getServerConfig().JWT_SECRET,function(t,o){return __awaiter(s,void 0,void 0,function(){var r;return __generator(this,function(e){switch(e.label){case 0:return t?(i(!1,401,"Unauthorized"),[3,5]):[3,1];case 1:n.req.id_user=o.id_user,e.label=2;case 2:return e.trys.push([2,4,,5]),[4,user_collection_1.Users.findById(o.id_user)];case 3:return(r=e.sent())?(n.req.user=r.fullname,n.req.user_readonly=r.readonly||!1,n.req.doc_user=r,i(!0)):i(!1),[3,5];case 4:return e.sent(),i(!1),[3,5];case 5:return[2]}})})}):i(!1,401,"Unauthorized")}return[2]})})}})},ResolveIOMainServer.prototype.listen=function(){var s=this;this._serverHTTP.listen(this._portHTTP,function(){console.log("Running server on port %s",s._portHTTP)}),this._serverWSS.on("listening",function(){console.log("Running server on port %s",s._portWSS)}),this._serverWSS.on("connection",function(o,e){var r;e.url&&e.url.includes("workerToken=")?(r=(0,common_1.objectIdHexString)(),o.id_worker=r,s._workers.push({id:r,ws:o,activeTasks:0,maxConcurrency:2}),console.log(new Date,"Worker connected:",r),o.on("message",function(e){s.handleWorkerMessage(r,e)}),o.on("close",function(){console.log(new Date,"Worker disconnected:",r),s._workers=s._workers.filter(function(e){return e.id!==r})})):(o.id_socket=(0,common_1.objectIdHexString)(),o.id_user=e.id_user,o.user=e.user,o.user_readonly=e.user_readonly,o.doc_user=e.doc_user,s._websocketManager.addWebSocket(o),s._subscriptionManager.createLoggedInUser(o.id_socket).then(function(){setTimeout(function(){o.pingTime=new Date,o.send("ping",function(e){e&&(s._subscriptionManager.getEnableDebug()&&console.log(new Date,"Server App","Error WS Ping"),s.unsubscribeWS(o))})},5e3)}),"DEBUG"===s.LOGGER&&console.log("Connection from user: "+e.user),o.isAlive=!0,o.retryCnt=0,o.on("message",function(t){return __awaiter(s,void 0,void 0,function(){var r;return __generator(this,function(e){this._debugMsgRecv+=1,r=[];try{r=JSON.parse(t,common_1.dateReviver)}catch(e){return console.log("Error - JSON.parse",t),this._methodManager.sendEmail("dev@resolveio.com","SERVER - JSON Parse Error - "+resolveio_server_app_1.ResolveIOServer.getServerConfig().CLIENT_NAME,JSON.stringify([t,e])),[2]}return this.processSocketMessage(o,r),[2]})})}).on("end",function(){s.unsubscribeWS(o)}).on("close",function(){s.unsubscribeWS(o)}).on("error",function(e){s.unsubscribeWS(o)}))}),setInterval(function(){s._serverWSS.clients.forEach(function(r){r.pingTime&&2e4<=Date.now()-r.pingTime.getTime()&&(!1===r.isAlive?(r.retryCnt++,3<=r.retryCnt?s.unsubscribeWS(r):(r.pingTime=new Date,r.send("ping",function(e){e&&(s._subscriptionManager.getEnableDebug()&&console.log(new Date,"Server App","Error WS Ping"),s.unsubscribeWS(r))}))):(r.retryCnt=0,r.isAlive=!1,r.pingTime=new Date,r.send("ping",function(e){e&&(s._subscriptionManager.getEnableDebug()&&console.log(new Date,"Server App","Error WS Ping"),s.unsubscribeWS(r))})))})},2e4)},ResolveIOMainServer.prototype.processSocketMessage=function(i,a){return __awaiter(this,void 0,void 0,function(){var r,t,o,s,n;return __generator(this,function(e){switch(e.label){case 0:if("string"==typeof a&&"ping"===a)return i&&i.readyState===i.OPEN&&i.send("pong"),[2];if("string"==typeof a&&"pong"===a)return i.isAlive=!0,i.pongTime=new Date,i.latency=moment.duration(moment(i.pongTime).diff(i.pingTime)).asMilliseconds(),this._subscriptionManager.loggedInLatency(i),[2];if(!Array.isArray(a[0]))return console.log("Invalid message format (expected array of arrays)",a),[2];e.label=1;case 1:e.trys.push([1,6,7,8]),r=__values(a),t=r.next(),e.label=2;case 2:return t.done?[3,5]:(o=t.value,[4,this.handleClientMessage(i,o)]);case 3:e.sent(),e.label=4;case 4:return t=r.next(),[3,2];case 5:return[3,8];case 6:return o=e.sent(),s={error:o},[3,8];case 7:try{t&&!t.done&&(n=r.return)&&n.call(r)}finally{if(s)throw s.error}return[7];case 8:return[2]}})})},ResolveIOMainServer.prototype.handleClientMessage=function(p,f){return __awaiter(this,void 0,void 0,function(){var r,t,o,s,n,i,a,l,c,u,_,g,v,d,h;return __generator(this,function(e){switch(e.label){case 0:return(r=f[0],a=f[1],t=f[2],o=f[3],this.publicProgram||!this._clientRoutes.some(function(e){return r.includes(e)})||p.doc_user.roles.groups.some(function(e){return e.views.some(function(e){return r.includes(e)||e.includes(r)})})||p.doc_user.roles.super_admin)?"subscription"!==o?[3,1]:(s=f[4],c=f[5],"sub"===s?this._subscriptionManager.subscribe(r,a,p,t,c,f.slice(6)):this._subscriptionManager.unsubscribe(r,a,p,t,c,f.slice(6)),[3,11]):[2];case 1:if(this.publicProgram||"offline"!==o)return[3,10];s={messageId:t,hasError:!1,data:"ACK"},p&&p.readyState===p.OPEN&&this._websocketManager.send(p,s),this._offlineUpdates.push(p),n=f[4],i=0,e.label=2;case 2:if(!(i<n.length))return[3,9];if(a=n[i],l=a.data,l.shift(),l.shift(),c=l.shift(),l.shift(),u=l.shift(),h={messageId:c,hasError:!1,data:"ACK"},p&&p.readyState===p.OPEN&&this._websocketManager.send(p,h),"insertDocument"===u&&"driver-gps"===l[0])return[3,8];if("reportBuilderGetResults"!==u&&"reportBuilderGetDistinctValue"!==u&&"reportBuilderBuildTree"!==u&&"generatePDF"!==u&&"getWOOfflineData"!==u&&"countQuery"!==u&&"countWithQuery"!==u&&"countCollectionWithQuery"!==u&&"find"!==u&&"findOne"!==u&&"findWithOptions"!==u&&"getDrivers"!==u&&"processAirdropDistribution"!==u&&("https://resolveio.com"!==resolveio_server_app_1.ResolveIOServer.getServerConfig().ROOT_URL&&"http://localhost:4200"!==resolveio_server_app_1.ResolveIOServer.getServerConfig().ROOT_URL?resolveio_server_app_1.ResolveIOServer.getLocalLogManager().writeLog({type:"log",data:{_id:(0,common_1.objectIdHexString)(),type:"client-request",collection:"",id_document:"",payload:(0,common_1.getBinarySize)(JSON.stringify(l))<2e5?JSON.stringify(l,null,2):"Too Big",method:u,id_user:p.id_user||"",user:p.user||"",messageId:t,route:r}}):log_collection_1.Logs.insertOne({_id:(0,common_1.objectIdHexString)(),type:"client-request",collection:"",id_document:"",payload:(0,common_1.getBinarySize)(JSON.stringify(l))<2e5?JSON.stringify(l,null,2):"Too Big",method:u,id_user:p.id_user||"",user:p.user||"",messageId:t,route:r,client:"ResolveIO",instance:"backend.resolveio.com"})),!this._methodManager._methods[u])return[3,7];e.label=3;case 3:return e.trys.push([3,5,,6]),[4,(h=this._methodManager.callMethod).call.apply(h,__spreadArray([Object.assign({},this._methodManager,method_manager_1.MethodManager.prototype,{id_user:p.id_user,user:p.user,id_ws:p.id_socket}),u],__read(l),!1))];case 4:return e.sent(),[3,6];case 5:return _=e.sent(),console.log(new Date,"Offline Error",JSON.stringify(_,null,2)),[3,6];case 6:return"updateDocumentOffline"!==u&&"updateDocumentPropsOffline"!==u||resolveio_server_app_1.ResolveIOServer.getMongoManager().invalidateQueryCache(l[0]),[3,8];case 7:console.log("Offline - Could not find method: "+u),e.label=8;case 8:return i++,[3,2];case 9:return this._offlineUpdates.splice(this._offlineUpdates.map(function(e){return e.id_socket}).indexOf(p.id_socket),1),[3,11];case 10:if(_=__spreadArray([],__read(f),!1),_.shift(),_.shift(),g=_.shift(),"method"===_.shift()){if(v=_.shift(),p.user_readonly)return[2];"reportBuilderGetResults"!==v&&"reportBuilderGetDistinctValue"!==v&&"reportBuilderBuildTree"!==v&&"generatePDF"!==v&&"getWOOfflineData"!==v&&"countQuery"!==v&&"countWithQuery"!==v&&"countCollectionWithQuery"!==v&&"find"!==v&&"findOne"!==v&&"findWithOptions"!==v&&"getDrivers"!==v&&"processAirdropDistribution"!==v&&("https://resolveio.com"!==resolveio_server_app_1.ResolveIOServer.getServerConfig().ROOT_URL&&"http://localhost:4200"!==resolveio_server_app_1.ResolveIOServer.getServerConfig().ROOT_URL?resolveio_server_app_1.ResolveIOServer.getLocalLogManager().writeLog({type:"log",data:{_id:(0,common_1.objectIdHexString)(),type:"client-request",collection:"",id_document:"",payload:(0,common_1.getBinarySize)(JSON.stringify(_))<2e5?JSON.stringify(_,null,2):"Too Big",method:v,id_user:p.id_user||"",user:p.user||"",messageId:t,route:r}}):log_collection_1.Logs.insertOne({_id:(0,common_1.objectIdHexString)(),type:"client-request",collection:"",id_document:"",payload:(0,common_1.getBinarySize)(JSON.stringify(_))<2e5?JSON.stringify(_,null,2):"Too Big",method:v,id_user:p.id_user||"",user:p.user||"",messageId:t,route:r,client:"ResolveIO",instance:"backend.resolveio.com"})),d={messageId:g,hasError:!1,data:"ACK"},p&&p.readyState===p.OPEN&&this._websocketManager.send(p,d),d=this.findAvailableWorker(),this._isWorkersEnabled&&d&&"insertSubscriptionLog"!==v&&"countQuery"!==v&&"incCounter"!==v&&"supportCreateBillingUser"!==v&&"find"!==v&&"insertDocument"!==v&&"countWithQuery"!==v&&"findOne"!==v&&"updateDocumentProps"!==v&&"findWithOptions"!==v&&"getSignedUrl"!==v&&"updateDocument"!==v&&"insertErrorLog"!==v&&"getSignedUrls"!==v&&"removeDocument"!==v&&"getSignedUrlWithId"!==v&&"incorrectUser"!==v&&"reloadWS"!==v&&"reconnectWS"!==v&&"disconnectWS"!==v?(d="task-"+(0,common_1.objectIdHexString)(),this._inFlightRequests[d]={ws:p,messageId:g,method:v},this.queueTask(d,v,_,{id_user:p.id_user,user:p.user,id_ws:p.id_socket})):this.callMethodLocally(p,g,v,_)}e.label=11;case 11:return[2]}})})},ResolveIOMainServer.prototype.callMethodLocally=function(s,n,i,a){return __awaiter(this,void 0,void 0,function(){var r,t,o;return __generator(this,function(e){switch(e.label){case 0:r={messageId:n,hasError:!1,data:null},e.label=1;case 1:return e.trys.push([1,3,,4]),[4,(o=this._methodManager.callMethod).call.apply(o,__spreadArray([Object.assign({},this._methodManager,method_manager_1.MethodManager.prototype,{id_user:s.id_user,user:s.user,id_ws:s.id_socket}),i],__read(a),!1))];case 2:return o=e.sent(),r.data=o,[3,4];case 3:return t=e.sent(),r.hasError=!0,r.data=t.message||"Unknown error",[3,4];case 4:return s&&s.readyState===s.OPEN&&this._websocketManager.send(s,r),[2]}})})},ResolveIOMainServer.prototype.queueTask=function(e,r,t,o){this._taskQueue.push({taskId:e,method:r,params:t,userContext:o}),this.dispatchQueue()},ResolveIOMainServer.prototype.dispatchQueue=function(){if(this._taskQueue.length)for(var e=0;e<9999;e++){var r=this._taskQueue[0];if(!r)break;var t=this.findAvailableWorker();if(!t)break;this._taskQueue.shift(),this.assignTaskToWorker(t,r)}},ResolveIOMainServer.prototype.findAvailableWorker=function(){var e=this._workers.filter(function(e){return e.activeTasks<e.maxConcurrency});return e.length?(e.sort(function(e,r){return e.activeTasks-r.activeTasks}),e[0]):null},ResolveIOMainServer.prototype.assignTaskToWorker=function(r,t){r.activeTasks++;var e={type:"task",taskId:t.taskId,method:t.method,params:t.params,userContext:t.userContext};try{r.ws.send(JSON.stringify(e)),console.log("Assigned task",t.taskId,"to worker",r.id)}catch(e){console.error("Failed to send task to worker:",e),r.activeTasks=Math.max(0,r.activeTasks-1),this._taskQueue.unshift(t)}},ResolveIOMainServer.prototype.handleWorkerMessage=function(r,t){var e,o,s,n;try{n=JSON.parse(t,common_1.dateReviver)}catch(e){return void console.error("Failed to parse worker message:",t)}"taskComplete"===n.type&&((t=this._workers.find(function(e){return e.id===r}))?(t.activeTasks=Math.max(0,t.activeTasks-1),t=n.taskId,e=n.error,o=n.message,n=n.result,(s=this._inFlightRequests[t])?(delete this._inFlightRequests[t],n={messageId:s.messageId,hasError:!1,data:n},e&&(n.hasError=!0,n.data=o),s.ws&&s.ws.readyState===s.ws.OPEN&&this._websocketManager.send(s.ws,n)):console.error("No in-flight request found for task:",t),this.dispatchQueue()):console.error("Unknown worker for taskComplete:",r))},ResolveIOMainServer.prototype.unsubscribeWS=function(e){this._subscriptionManager&&this._subscriptionManager.getEnableDebug()&&console.log(new Date,"Server App","Unsub WS",e.user,e.id_socket),this._subscriptionManager.unsubscribeAll(e),e.removeAllListeners()},ResolveIOMainServer.prototype.getApp=function(){return this._app},ResolveIOMainServer.prototype.getServerConfig=function(){return resolveio_server_app_1.ResolveIOServer.getServerConfig()},ResolveIOMainServer}();exports.ResolveIOMainServer=ResolveIOMainServer;
|
|
1
|
+
"use strict";var __awaiter=this&&this.__awaiter||function(e,o,n,s){return new(n=n||Promise)(function(t,r){function fulfilled(e){try{step(s.next(e))}catch(e){r(e)}}function rejected(e){try{step(s.throw(e))}catch(e){r(e)}}function step(e){var r;e.done?t(e.value):((r=e.value)instanceof n?r:new n(function(e){e(r)})).then(fulfilled,rejected)}step((s=s.apply(e,o||[])).next())})},__generator=this&&this.__generator||function(o,n){var s,i,a,l={label:0,sent:function(){if(1&a[0])throw a[1];return a[1]},trys:[],ops:[]},c={next:verb(0),throw:verb(1),return:verb(2)};return"function"==typeof Symbol&&(c[Symbol.iterator]=function(){return this}),c;function verb(t){return function(e){var r=[t,e];if(s)throw new TypeError("Generator is already executing.");for(;l=c&&r[c=0]?0:l;)try{if(s=1,i&&(a=2&r[0]?i.return:r[0]?i.throw||((a=i.return)&&a.call(i),0):i.next)&&!(a=a.call(i,r[1])).done)return a;switch(i=0,(r=a?[2&r[0],a.value]:r)[0]){case 0:case 1:a=r;break;case 4:return l.label++,{value:r[1],done:!1};case 5:l.label++,i=r[1],r=[0];continue;case 7:r=l.ops.pop(),l.trys.pop();continue;default:if(!(a=0<(a=l.trys).length&&a[a.length-1])&&(6===r[0]||2===r[0])){l=0;continue}if(3===r[0]&&(!a||r[1]>a[0]&&r[1]<a[3]))l.label=r[1];else if(6===r[0]&&l.label<a[1])l.label=a[1],a=r;else{if(!(a&&l.label<a[2])){a[2]&&l.ops.pop(),l.trys.pop();continue}l.label=a[2],l.ops.push(r)}}r=n.call(o,l)}catch(e){r=[6,e],i=0}finally{s=a=0}if(5&r[0])throw r[1];return{value:r[0]?r[1]:void 0,done:!0}}}},__read=this&&this.__read||function(e,r){var t="function"==typeof Symbol&&e[Symbol.iterator];if(!t)return e;var o,n,s=t.call(e),i=[];try{for(;(void 0===r||0<r--)&&!(o=s.next()).done;)i.push(o.value)}catch(e){n={error:e}}finally{try{o&&!o.done&&(t=s.return)&&t.call(s)}finally{if(n)throw n.error}}return i},__spreadArray=this&&this.__spreadArray||function(e,r,t){if(t||2===arguments.length)for(var o,n=0,s=r.length;n<s;n++)!o&&n in r||((o=o||Array.prototype.slice.call(r,0,n))[n]=r[n]);return e.concat(o||Array.prototype.slice.call(r))},__values=this&&this.__values||function(e){var r="function"==typeof Symbol&&Symbol.iterator,t=r&&e[r],o=0;if(t)return t.call(e);if(e&&"number"==typeof e.length)return{next:function(){return{value:(e=e&&o>=e.length?void 0:e)&&e[o++],done:!e}}};throw new TypeError(r?"Object is not iterable.":"Symbol.iterator is not defined.")},http_1=(Object.defineProperty(exports,"__esModule",{value:!0}),exports.ResolveIOMainServer=void 0,require("http")),express=require("express"),bodyParser=require("body-parser"),xmlParser=require("express-xml-bodyparser"),WebSocket=require("ws"),jwt=require("jsonwebtoken"),moment=require("moment-timezone"),common_1=require("./util/common"),cron_manager_1=require("./managers/cron.manager"),method_manager_1=require("./managers/method.manager"),subscription_manager_1=require("./managers/subscription.manager"),monitor_manager_1=require("./managers/monitor.manager"),log_collection_1=require("./collections/log.collection"),user_collection_1=require("./collections/user.collection"),home_1=require("./http/home"),auth_1=require("./http/auth"),health_1=require("./http/health"),mongodb_1=require("mongodb"),websocket_manager_1=require("./managers/websocket.manager"),resolveio_server_app_1=require("./resolveio-server-app"),ResolveIOMainServer=function(){function ResolveIOMainServer(){this._offlineUpdates=[],this.sesMail=!1,this.standardProgram=!1,this.publicProgram=!1,this._rebootFlag=!1,this.LOGGER="ERROR",this._clientRoutes=[],this._lastErrorMsg=null,this._debugMsgRecv=0,this._debugMsgQueue=0,this._isWorkersEnabled=!1,this._isWorkerInstance=!1,this._safeShutdown=!1,this._workers=[],this._taskQueue=[],this._inFlightRequests={},this._serverStartTime=new Date,this._lastErrorMsg=null,this._monitorManager=new monitor_manager_1.MonitorManager,this._monitorManagerFunction=new monitor_manager_1.MonitorManagerFunction}return ResolveIOMainServer.prototype.initServerApp=function(){var e=this;this._isWorkersEnabled="true"===process.env.IS_WORKERS_ENABLED,this._isWorkerInstance="true"===process.env.IS_WORKER_INSTANCE,setInterval(function(){e._subscriptionManager&&e._subscriptionManager.getEnableDebug()&&(console.log(new Date,"Server App","Msg Recv Hits",e._debugMsgRecv),console.log(new Date,"Server App","Msg Queue Hits",e._debugMsgQueue)),e._debugMsgQueue=0,e._debugMsgRecv=0},6e4),process.on("unhandledRejection",function(o,n){return __awaiter(e,void 0,void 0,function(){var r,t=this;return __generator(this,function(e){switch(e.label){case 0:return o&&"MongoError"===o.name&&48===o.code?[2]:(console.error(new Date,"Unhandled Rejection at Promise",[o,n]),r=moment().diff(this._serverStartTime,"seconds"),o&&("MongoNetworkTimeoutError"===o.name||o instanceof mongodb_1.MongoNetworkTimeoutError)?60<r&&!this._lastErrorMsg?(this._lastErrorMsg=new Date,setTimeout(function(){t._lastErrorMsg=null},6e4),[4,this._methodManager.sendEmail("dev@resolveio.com","SERVER - MongoNetworkTimeoutError - Quitting NodeJS - "+resolveio_server_app_1.ResolveIOServer.getServerConfig().CLIENT_NAME,JSON.stringify({name:o.name,message:o.message,stack:o.stack},null,2))]):[3,2]:[3,3]);case 1:e.sent(),process.exit(1),e.label=2;case 2:return[3,10];case 3:return o&&"MongoError"===o.name&&"not master"===o.message?60<r&&!this._lastErrorMsg?(this._lastErrorMsg=new Date,setTimeout(function(){t._lastErrorMsg=null},6e4),[4,this._methodManager.sendEmail("dev@resolveio.com","SERVER - Unhandled Rejection - Quitting NodeJS - "+resolveio_server_app_1.ResolveIOServer.getServerConfig().CLIENT_NAME,JSON.stringify([o.name,o.message,o.stack],null,2))]):[3,5]:[3,6];case 4:e.sent(),e.label=5;case 5:return process.exit(1),[3,10];case 6:return o&&"MongoError"===o.name&&"not master and slaveOk=false"===o.message?60<r&&!this._lastErrorMsg?(this._lastErrorMsg=new Date,setTimeout(function(){t._lastErrorMsg=null},6e4),[4,this._methodManager.sendEmail("dev@resolveio.com","SERVER - Unhandled Rejection - Quitting NodeJS - "+resolveio_server_app_1.ResolveIOServer.getServerConfig().CLIENT_NAME,JSON.stringify([o.name,o.message,o.stack],null,2))]):[3,8]:[3,9];case 7:e.sent(),e.label=8;case 8:return process.exit(1),[3,10];case 9:o&&"StatusError"!==o.name&&""!==o.message&&60<r&&!this._lastErrorMsg&&(this._lastErrorMsg=new Date,setTimeout(function(){t._lastErrorMsg=null},6e4),this._methodManager.sendEmail("dev@resolveio.com","SERVER - Unhandled Rejection - "+resolveio_server_app_1.ResolveIOServer.getServerConfig().CLIENT_NAME,JSON.stringify([o.name,o.message,o.stack],null,2))),e.label=10;case 10:return[2]}})})}),process.on("uncaughtException",function(t){return __awaiter(e,void 0,void 0,function(){var r=this;return __generator(this,function(e){switch(e.label){case 0:return(console.error(t,"Uncaught Exception thrown"),60<moment().diff(this._serverStartTime,"seconds")&&!this._lastErrorMsg)?(this._lastErrorMsg=new Date,setTimeout(function(){r._lastErrorMsg=null},6e4),[4,this._methodManager.sendEmail("dev@resolveio.com","SERVER - Unhandled Exception - "+resolveio_server_app_1.ResolveIOServer.getServerConfig().CLIENT_NAME,JSON.stringify([t.name,t.message,t.stack],null,2))]):[3,2];case 1:e.sent(),e.label=2;case 2:return[2]}})})}),process.on("SIGINT",function(){e._rebootFlag=!0,e._serverHTTP&&e._serverHTTP.close(),e.safeShutdown()}),process.on("SIGTERM",function(){e._rebootFlag=!0,e._serverHTTP&&e._serverHTTP.close(),e.safeShutdown()}),process.on("SIGQUIT",function(){e._rebootFlag=!0,e._serverHTTP&&e._serverHTTP.close(),e.safeShutdown()}),"DEBUG"===this.LOGGER&&console.log("Starting ResolveIO Server"),this._isWorkersEnabled?this._isWorkerInstance?(console.log("Running as a Worker instance"),this._methodManager=new method_manager_1.MethodManager(this._monitorManagerFunction,this._isWorkersEnabled,this._isWorkerInstance),this._cronManager=new cron_manager_1.CronManager,this.startWorkerInstance()):(console.log("Running as a Server instance"),this._websocketManager=new websocket_manager_1.WebSocketManager(this),this.startServerInstance(),this._methodManager=new method_manager_1.MethodManager(this._monitorManagerFunction,this._isWorkersEnabled,this._isWorkerInstance),this._subscriptionManager=new subscription_manager_1.SubscriptionManager(this._serverWSS,resolveio_server_app_1.ResolveIOServer.getServerConfig(),this._monitorManagerFunction),this.listen()):(console.log("Running with Workers Disabled"),this._websocketManager=new websocket_manager_1.WebSocketManager(this),this.startServerInstance(),this._methodManager=new method_manager_1.MethodManager(this._monitorManagerFunction,this._isWorkersEnabled,this._isWorkerInstance),this._subscriptionManager=new subscription_manager_1.SubscriptionManager(this._serverWSS,resolveio_server_app_1.ResolveIOServer.getServerConfig(),this._monitorManagerFunction),this._cronManager=new cron_manager_1.CronManager,this.listen())},ResolveIOMainServer.prototype.startServerInstance=function(){this._app=express(),this._app.use(bodyParser.json({limit:"50mb",reviver:common_1.dateReviver})),this._app.use(bodyParser.urlencoded({limit:"50mb",extended:!0,parameterLimit:1e6})),this._app.use(xmlParser()),this._portHTTP=process.env.PORT_HTTP||resolveio_server_app_1.ResolveIOServer.getServerConfig().PORT_HTTP||8080,this._portWSS=process.env.PORT_WSS||resolveio_server_app_1.ResolveIOServer.getServerConfig().PORT_WSS||8081,"DEBUG"===this.LOGGER&&console.log("Setup ports"),this.createServer(),"DEBUG"===this.LOGGER&&console.log("Create server"),this._app.use(function(e,r,t){r.setHeader("Access-Control-Allow-Origin","*"),r.setHeader("Access-Control-Allow-Methods","GET, POST"),r.setHeader("Access-Control-Allow-Headers","X-Requested-With,content-type"),r.setHeader("Access-Control-Allow-Credentials","false"),t()}),"DEBUG"===this.LOGGER&&console.log("Setup cors"),(0,auth_1.setupAuthRoutes)(this,this._app,resolveio_server_app_1.ResolveIOServer.getServerConfig()),(0,health_1.setupHealthRoutes)(this._app,resolveio_server_app_1.ResolveIOServer.getServerConfig()),"ResolveIO"!==resolveio_server_app_1.ResolveIOServer.getServerConfig().CLIENT_NAME&&!this.standardProgram||(0,home_1.setupHomeRoutes)(this,this._app,resolveio_server_app_1.ResolveIOServer.getServerConfig()),"DEBUG"===this.LOGGER&&console.log("Setup express routes")},ResolveIOMainServer.prototype.startWorkerInstance=function(){return __awaiter(this,void 0,void 0,function(){var t,n,s=this;return __generator(this,function(e){return console.log(new Date,"Worker instance started, connecting to main server via WebSocket..."),t=resolveio_server_app_1.ResolveIOServer.getServerConfig().SERVER_URL+"/websocket?workerToken="+resolveio_server_app_1.ResolveIOServer.getServerConfig().WORKER_TOKEN,(n=function(){var o=new WebSocket(t),e=null,r=(o&&o.readyState===o.OPEN&&o.ping(),setInterval(function(){e?(e=null,o&&o.readyState===o.OPEN&&o.ping()):o.close()},15e3));o.on("open",function(){console.log(new Date,"Connected to main server as worker",process.env.WORKER_INDEX,process.env.NODE_APP_INSTANCE)}),o.on("ping",function(){o.pong()}),o.on("pong",function(){e=new Date}),o.on("message",function(t){return __awaiter(s,void 0,void 0,function(){var r;return __generator(this,function(e){try{r=JSON.parse(t.toString(),common_1.dateReviver)}catch(e){return console.error("Worker parse error",e),[2]}return"task"===r.type&&this.handleIncomingTask(o,r),[2]})})}),o.on("close",function(){console.log(new Date,"Disconnected from main server. Reconnecting in 5s..."),setTimeout(n,5e3),clearInterval(r)}),o.on("error",function(e){console.error(new Date,"Worker WS error:",e),o.close()})})(),[2]})})},ResolveIOMainServer.prototype.handleIncomingTask=function(u,_){return __awaiter(this,void 0,void 0,function(){var r,t,o,n,s,i,a,l,c=this;return __generator(this,function(e){switch(e.label){case 0:if(r=_.taskId,t=_.method,o=_.params,n=_.userContext,!r||!t)return console.log("Invalid task message received",_),[2];s=!1,i=setTimeout(function(){s=!0,console.error("Worker timed out on task:",r),c.sendWorkerResponse(u,{type:"taskComplete",taskId:r,error:!0,message:"Task timed out"})},12e4),e.label=1;case 1:return e.trys.push([1,3,,4]),a=Object.assign({},this._methodManager,method_manager_1.MethodManager.prototype,{id_user:(null==n?void 0:n.id_user)||"",user:(null==n?void 0:n.user)||"",id_ws:(null==n?void 0:n.id_ws)||""}),[4,(l=this._methodManager.callMethod).call.apply(l,__spreadArray([a,t],__read(o),!1))];case 2:return l=e.sent(),s||(clearTimeout(i),this.sendWorkerResponse(u,{type:"taskComplete",taskId:r,error:!1,result:l})),[3,4];case 3:return a=e.sent(),s||(clearTimeout(i),console.error("Worker failed task:",r,a),this.sendWorkerResponse(u,{type:"taskComplete",taskId:r,error:!0,message:a.message||"Unknown error"})),[3,4];case 4:return[2]}})})},ResolveIOMainServer.prototype.sendWorkerResponse=function(e,r){try{e.send(JSON.stringify(r))}catch(e){console.error("Failed to send worker response:",e)}},ResolveIOMainServer.prototype.safeShutdown=function(){var e=this;this._safeShutdown||console.log(new Date,"Safe Shutdown Command Received"),this._monitorManagerFunction.getActiveMonitorFunctions().length||this._offlineUpdates.length?(this._safeShutdown||(this._safeShutdown=!0,setTimeout(function(){e._safeShutdown=!1},1e3),console.log(new Date,"Safe Exit In Progress",this._monitorManagerFunction.getActiveMonitorFunctions().length,this._offlineUpdates.length)),setImmediate(function(){e.safeShutdown()})):resolveio_server_app_1.ResolveIOServer.getMongoConnection()?resolveio_server_app_1.ResolveIOServer.getMongoConnection().close(!1).then(function(){console.log(new Date,"Safe Exit Complete, Process Exit"),process.exit(0)},function(){process.exit(1)}):process.exit(0)},ResolveIOMainServer.prototype.getIsWorkersEnabled=function(){return this._isWorkersEnabled},ResolveIOMainServer.prototype.getIsWorkerInstance=function(){return this._isWorkerInstance},ResolveIOMainServer.prototype.getWSList=function(){var r=[];return this._serverWSS.clients.forEach(function(e){r.push(e.id_socket)}),r},ResolveIOMainServer.prototype.getWSUserList=function(){var r=[];return this._serverWSS.clients.forEach(function(e){r.push(e.id_user)}),r},ResolveIOMainServer.prototype.getHTTPServer=function(){return this._serverHTTP},ResolveIOMainServer.prototype.getCronManager=function(){return this._cronManager},ResolveIOMainServer.prototype.getMethodManager=function(){return this._methodManager},ResolveIOMainServer.prototype.getSubscriptionManager=function(){return this._subscriptionManager},ResolveIOMainServer.prototype.getMonitorManager=function(){return this._monitorManager},ResolveIOMainServer.prototype.getRebootFlag=function(){return this._rebootFlag},ResolveIOMainServer.prototype.getWebSocketManager=function(){return this._websocketManager},ResolveIOMainServer.prototype.createServer=function(){var e=this;this._serverHTTP=(0,http_1.createServer)(this._app),this._serverHTTP.keepAliveTimeout=65e3,this._serverHTTP.headersTimeout=66e3,this._serverWSS=new WebSocket.Server({port:this._portWSS,verifyClient:this.publicProgram?null:function(s,i){return __awaiter(e,void 0,void 0,function(){var r,t,n=this;return __generator(this,function(e){if(this._rebootFlag)i(!1,409,"Unable To Process");else{if("DEBUG"===this.LOGGER&&console.log("Verify Client",s,i),s.req.url&&s.req.url.includes("workerToken="))return r=s.req.url.split("workerToken="),(r[1]||"")===resolveio_server_app_1.ResolveIOServer.getServerConfig().WORKER_TOKEN?i(!0):i(!1,401,"Unauthorized"),[2];r=s.req.headers["sec-websocket-protocol"].split(/,/),(s.origin===resolveio_server_app_1.ResolveIOServer.getServerConfig().ROOT_URL||s.origin===resolveio_server_app_1.ResolveIOServer.getServerConfig().SEC_ROOT_URL||s.origin===resolveio_server_app_1.ResolveIOServer.getServerConfig().RESOLVEIO_URL||s.origin===resolveio_server_app_1.ResolveIOServer.getServerConfig().RESOLVEIO_SECONDARY_URL)&&(t=r[0])?jwt.verify(t,resolveio_server_app_1.ResolveIOServer.getServerConfig().JWT_SECRET,function(t,o){return __awaiter(n,void 0,void 0,function(){var r;return __generator(this,function(e){switch(e.label){case 0:return t?(i(!1,401,"Unauthorized"),[3,5]):[3,1];case 1:s.req.id_user=o.id_user,e.label=2;case 2:return e.trys.push([2,4,,5]),[4,user_collection_1.Users.findById(o.id_user)];case 3:return(r=e.sent())?(s.req.user=r.fullname,s.req.user_readonly=r.readonly||!1,s.req.doc_user=r,i(!0)):i(!1),[3,5];case 4:return e.sent(),i(!1),[3,5];case 5:return[2]}})})}):i(!1,401,"Unauthorized")}return[2]})})}})},ResolveIOMainServer.prototype.listen=function(){var s=this;this._serverHTTP.listen(this._portHTTP,function(){console.log("Running server on port %s",s._portHTTP)}),this._serverWSS.on("listening",function(){console.log("Running server on port %s",s._portWSS)}),this._serverWSS.on("connection",function(o,e){var r,t,n;e.url&&e.url.includes("workerToken=")?(r=(0,common_1.objectIdHexString)(),o.id_worker=r,s._workers.push({id:r,ws:o,activeTasks:0,maxConcurrency:2}),t=null,o&&o.readyState===o.OPEN&&o.ping(),n=setInterval(function(){t?(t=null,o&&o.readyState===o.OPEN&&o.ping()):o.close()},15e3),console.log(new Date,"Worker connected:",r),o.on("message",function(e){s.handleWorkerMessage(r,e)}),o.on("ping",function(){o.pong()}),o.on("pong",function(){t=new Date}),o.on("close",function(){console.log(new Date,"Worker disconnected:",r),s._workers=s._workers.filter(function(e){return e.id!==r}),clearInterval(n)})):(o.id_socket=(0,common_1.objectIdHexString)(),o.id_user=e.id_user,o.user=e.user,o.user_readonly=e.user_readonly,o.doc_user=e.doc_user,s._websocketManager.addWebSocket(o),s._subscriptionManager.createLoggedInUser(o.id_socket).then(function(){setTimeout(function(){o.pingTime=new Date,o.send("ping",function(e){e&&(s._subscriptionManager.getEnableDebug()&&console.log(new Date,"Server App","Error WS Ping"),s.unsubscribeWS(o))})},5e3)}),"DEBUG"===s.LOGGER&&console.log("Connection from user: "+e.user),o.isAlive=!0,o.retryCnt=0,o.on("message",function(t){return __awaiter(s,void 0,void 0,function(){var r;return __generator(this,function(e){this._debugMsgRecv+=1,r=[];try{r=JSON.parse(t,common_1.dateReviver)}catch(e){return console.log("Error - JSON.parse",t),this._methodManager.sendEmail("dev@resolveio.com","SERVER - JSON Parse Error - "+resolveio_server_app_1.ResolveIOServer.getServerConfig().CLIENT_NAME,JSON.stringify([t,e])),[2]}return this.processSocketMessage(o,r),[2]})})}).on("end",function(){s.unsubscribeWS(o)}).on("close",function(){s.unsubscribeWS(o)}).on("error",function(e){s.unsubscribeWS(o)}))}),setInterval(function(){s._serverWSS.clients.forEach(function(r){r.pingTime&&2e4<=Date.now()-r.pingTime.getTime()&&(!1===r.isAlive?(r.retryCnt++,3<=r.retryCnt?s.unsubscribeWS(r):(r.pingTime=new Date,r.send("ping",function(e){e&&(s._subscriptionManager.getEnableDebug()&&console.log(new Date,"Server App","Error WS Ping"),s.unsubscribeWS(r))}))):(r.retryCnt=0,r.isAlive=!1,r.pingTime=new Date,r.send("ping",function(e){e&&(s._subscriptionManager.getEnableDebug()&&console.log(new Date,"Server App","Error WS Ping"),s.unsubscribeWS(r))})))})},2e4)},ResolveIOMainServer.prototype.processSocketMessage=function(i,a){return __awaiter(this,void 0,void 0,function(){var r,t,o,n,s;return __generator(this,function(e){switch(e.label){case 0:if("string"==typeof a&&"ping"===a)return i&&i.readyState===i.OPEN&&i.send("pong"),[2];if("string"==typeof a&&"pong"===a)return i.isAlive=!0,i.pongTime=new Date,i.latency=moment.duration(moment(i.pongTime).diff(i.pingTime)).asMilliseconds(),this._subscriptionManager.loggedInLatency(i),[2];if(!Array.isArray(a[0]))return console.log("Invalid message format (expected array of arrays)",a),[2];e.label=1;case 1:e.trys.push([1,6,7,8]),r=__values(a),t=r.next(),e.label=2;case 2:return t.done?[3,5]:(o=t.value,[4,this.handleClientMessage(i,o)]);case 3:e.sent(),e.label=4;case 4:return t=r.next(),[3,2];case 5:return[3,8];case 6:return o=e.sent(),n={error:o},[3,8];case 7:try{t&&!t.done&&(s=r.return)&&s.call(r)}finally{if(n)throw n.error}return[7];case 8:return[2]}})})},ResolveIOMainServer.prototype.handleClientMessage=function(h,f){return __awaiter(this,void 0,void 0,function(){var r,t,o,n,s,i,a,l,c,u,_,g,v,d,p;return __generator(this,function(e){switch(e.label){case 0:return(r=f[0],a=f[1],t=f[2],o=f[3],this.publicProgram||!this._clientRoutes.some(function(e){return r.includes(e)})||h.doc_user.roles.groups.some(function(e){return e.views.some(function(e){return r.includes(e)||e.includes(r)})})||h.doc_user.roles.super_admin)?"subscription"!==o?[3,1]:(n=f[4],c=f[5],"sub"===n?this._subscriptionManager.subscribe(r,a,h,t,c,f.slice(6)):this._subscriptionManager.unsubscribe(r,a,h,t,c,f.slice(6)),[3,11]):[2];case 1:if(this.publicProgram||"offline"!==o)return[3,10];n={messageId:t,hasError:!1,data:"ACK"},h&&h.readyState===h.OPEN&&this._websocketManager.send(h,n),this._offlineUpdates.push(h),s=f[4],i=0,e.label=2;case 2:if(!(i<s.length))return[3,9];if(a=s[i],l=a.data,l.shift(),l.shift(),c=l.shift(),l.shift(),u=l.shift(),p={messageId:c,hasError:!1,data:"ACK"},h&&h.readyState===h.OPEN&&this._websocketManager.send(h,p),"insertDocument"===u&&"driver-gps"===l[0])return[3,8];if("reportBuilderGetResults"!==u&&"reportBuilderGetDistinctValue"!==u&&"reportBuilderBuildTree"!==u&&"generatePDF"!==u&&"getWOOfflineData"!==u&&"countQuery"!==u&&"countWithQuery"!==u&&"countCollectionWithQuery"!==u&&"find"!==u&&"findOne"!==u&&"findWithOptions"!==u&&"getDrivers"!==u&&"processAirdropDistribution"!==u&&("https://resolveio.com"!==resolveio_server_app_1.ResolveIOServer.getServerConfig().ROOT_URL&&"http://localhost:4200"!==resolveio_server_app_1.ResolveIOServer.getServerConfig().ROOT_URL?resolveio_server_app_1.ResolveIOServer.getLocalLogManager().writeLog({type:"log",data:{_id:(0,common_1.objectIdHexString)(),type:"client-request",collection:"",id_document:"",payload:(0,common_1.getBinarySize)(JSON.stringify(l))<2e5?JSON.stringify(l,null,2):"Too Big",method:u,id_user:h.id_user||"",user:h.user||"",messageId:t,route:r}}):log_collection_1.Logs.insertOne({_id:(0,common_1.objectIdHexString)(),type:"client-request",collection:"",id_document:"",payload:(0,common_1.getBinarySize)(JSON.stringify(l))<2e5?JSON.stringify(l,null,2):"Too Big",method:u,id_user:h.id_user||"",user:h.user||"",messageId:t,route:r,client:"ResolveIO",instance:"backend.resolveio.com"})),!this._methodManager._methods[u])return[3,7];e.label=3;case 3:return e.trys.push([3,5,,6]),[4,(p=this._methodManager.callMethod).call.apply(p,__spreadArray([Object.assign({},this._methodManager,method_manager_1.MethodManager.prototype,{id_user:h.id_user,user:h.user,id_ws:h.id_socket}),u],__read(l),!1))];case 4:return e.sent(),[3,6];case 5:return _=e.sent(),console.log(new Date,"Offline Error",JSON.stringify(_,null,2)),[3,6];case 6:return"updateDocumentOffline"!==u&&"updateDocumentPropsOffline"!==u||resolveio_server_app_1.ResolveIOServer.getMongoManager().invalidateQueryCache(l[0]),[3,8];case 7:console.log("Offline - Could not find method: "+u),e.label=8;case 8:return i++,[3,2];case 9:return this._offlineUpdates.splice(this._offlineUpdates.map(function(e){return e.id_socket}).indexOf(h.id_socket),1),[3,11];case 10:if(_=__spreadArray([],__read(f),!1),_.shift(),_.shift(),g=_.shift(),"method"===_.shift()){if(v=_.shift(),h.user_readonly)return[2];"reportBuilderGetResults"!==v&&"reportBuilderGetDistinctValue"!==v&&"reportBuilderBuildTree"!==v&&"generatePDF"!==v&&"getWOOfflineData"!==v&&"countQuery"!==v&&"countWithQuery"!==v&&"countCollectionWithQuery"!==v&&"find"!==v&&"findOne"!==v&&"findWithOptions"!==v&&"getDrivers"!==v&&"processAirdropDistribution"!==v&&("https://resolveio.com"!==resolveio_server_app_1.ResolveIOServer.getServerConfig().ROOT_URL&&"http://localhost:4200"!==resolveio_server_app_1.ResolveIOServer.getServerConfig().ROOT_URL?resolveio_server_app_1.ResolveIOServer.getLocalLogManager().writeLog({type:"log",data:{_id:(0,common_1.objectIdHexString)(),type:"client-request",collection:"",id_document:"",payload:(0,common_1.getBinarySize)(JSON.stringify(_))<2e5?JSON.stringify(_,null,2):"Too Big",method:v,id_user:h.id_user||"",user:h.user||"",messageId:t,route:r}}):log_collection_1.Logs.insertOne({_id:(0,common_1.objectIdHexString)(),type:"client-request",collection:"",id_document:"",payload:(0,common_1.getBinarySize)(JSON.stringify(_))<2e5?JSON.stringify(_,null,2):"Too Big",method:v,id_user:h.id_user||"",user:h.user||"",messageId:t,route:r,client:"ResolveIO",instance:"backend.resolveio.com"})),d={messageId:g,hasError:!1,data:"ACK"},h&&h.readyState===h.OPEN&&this._websocketManager.send(h,d),d=this.findAvailableWorker(),this._isWorkersEnabled&&d&&"insertSubscriptionLog"!==v&&"countQuery"!==v&&"incCounter"!==v&&"supportCreateBillingUser"!==v&&"find"!==v&&"insertDocument"!==v&&"countWithQuery"!==v&&"findOne"!==v&&"updateDocumentProps"!==v&&"findWithOptions"!==v&&"getSignedUrl"!==v&&"updateDocument"!==v&&"insertErrorLog"!==v&&"getSignedUrls"!==v&&"removeDocument"!==v&&"getSignedUrlWithId"!==v&&"incorrectUser"!==v&&"reloadWS"!==v&&"reconnectWS"!==v&&"disconnectWS"!==v?(d="task-"+(0,common_1.objectIdHexString)(),this._inFlightRequests[d]={ws:h,messageId:g,method:v},this.queueTask(d,v,_,{id_user:h.id_user,user:h.user,id_ws:h.id_socket})):this.callMethodLocally(h,g,v,_)}e.label=11;case 11:return[2]}})})},ResolveIOMainServer.prototype.callMethodLocally=function(n,s,i,a){return __awaiter(this,void 0,void 0,function(){var r,t,o;return __generator(this,function(e){switch(e.label){case 0:r={messageId:s,hasError:!1,data:null},e.label=1;case 1:return e.trys.push([1,3,,4]),[4,(o=this._methodManager.callMethod).call.apply(o,__spreadArray([Object.assign({},this._methodManager,method_manager_1.MethodManager.prototype,{id_user:n.id_user,user:n.user,id_ws:n.id_socket}),i],__read(a),!1))];case 2:return o=e.sent(),r.data=o,[3,4];case 3:return t=e.sent(),r.hasError=!0,r.data=t.message||"Unknown error",[3,4];case 4:return n&&n.readyState===n.OPEN&&this._websocketManager.send(n,r),[2]}})})},ResolveIOMainServer.prototype.queueTask=function(e,r,t,o){this._taskQueue.push({taskId:e,method:r,params:t,userContext:o}),this.dispatchQueue()},ResolveIOMainServer.prototype.dispatchQueue=function(){if(this._taskQueue.length)for(var e=0;e<9999;e++){var r=this._taskQueue[0];if(!r)break;var t=this.findAvailableWorker();if(!t)break;this._taskQueue.shift(),this.assignTaskToWorker(t,r)}},ResolveIOMainServer.prototype.findAvailableWorker=function(){var e=this._workers.filter(function(e){return e.activeTasks<e.maxConcurrency});return e.length?(e.sort(function(e,r){return e.activeTasks-r.activeTasks}),e[0]):null},ResolveIOMainServer.prototype.assignTaskToWorker=function(r,t){r.activeTasks++;var e={type:"task",taskId:t.taskId,method:t.method,params:t.params,userContext:t.userContext};try{r.ws.send(JSON.stringify(e)),console.log("Assigned task",t.taskId,"to worker",r.id)}catch(e){console.error("Failed to send task to worker:",e),r.activeTasks=Math.max(0,r.activeTasks-1),this._taskQueue.unshift(t)}},ResolveIOMainServer.prototype.handleWorkerMessage=function(r,t){var e,o,n,s;try{s=JSON.parse(t,common_1.dateReviver)}catch(e){return void console.error("Failed to parse worker message:",t)}"taskComplete"===s.type&&((t=this._workers.find(function(e){return e.id===r}))?(t.activeTasks=Math.max(0,t.activeTasks-1),t=s.taskId,e=s.error,o=s.message,s=s.result,(n=this._inFlightRequests[t])?(delete this._inFlightRequests[t],s={messageId:n.messageId,hasError:!1,data:s},e&&(s.hasError=!0,s.data=o),n.ws&&n.ws.readyState===n.ws.OPEN&&this._websocketManager.send(n.ws,s)):console.error("No in-flight request found for task:",t),this.dispatchQueue()):console.error("Unknown worker for taskComplete:",r))},ResolveIOMainServer.prototype.unsubscribeWS=function(e){this._subscriptionManager&&this._subscriptionManager.getEnableDebug()&&console.log(new Date,"Server App","Unsub WS",e.user,e.id_socket),this._subscriptionManager.unsubscribeAll(e),e.removeAllListeners()},ResolveIOMainServer.prototype.getApp=function(){return this._app},ResolveIOMainServer.prototype.getServerConfig=function(){return resolveio_server_app_1.ResolveIOServer.getServerConfig()},ResolveIOMainServer}();exports.ResolveIOMainServer=ResolveIOMainServer;
|
|
2
2
|
//# sourceMappingURL=server-app.js.map
|
package/server-app.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/server-app.ts"],"names":["http_1","require","express","bodyParser","xmlParser","WebSocket","jwt","moment","common_1","cron_manager_1","method_manager_1","subscription_manager_1","monitor_manager_1","log_collection_1","user_collection_1","home_1","auth_1","health_1","mongodb_1","websocket_manager_1","resolveio_server_app_1","ResolveIOMainServer","this","_offlineUpdates","sesMail","standardProgram","publicProgram","_rebootFlag","LOGGER","_clientRoutes","_lastErrorMsg","_debugMsgRecv","_debugMsgQueue","_isWorkersEnabled","_isWorkerInstance","_safeShutdown","_workers","_taskQueue","_inFlightRequests","_serverStartTime","Date","_monitorManager","MonitorManager","_monitorManagerFunction","MonitorManagerFunction","prototype","initServerApp","_this","process","env","IS_WORKERS_ENABLED","IS_WORKER_INSTANCE","setInterval","_subscriptionManager","getEnableDebug","console","log","on","error","rej","__awaiter","diffTimeSec","diff","MongoNetworkTimeoutError","setTimeout","_methodManager","sendEmail","ResolveIOServer","getServerConfig","JSON","stringify","name","message","stack","_a","sent","exit","_serverHTTP","close","safeShutdown","MethodManager","_cronManager","CronManager","startWorkerInstance","_websocketManager","WebSocketManager","startServerInstance","SubscriptionManager","_serverWSS","listen","_app","use","json","limit","reviver","dateReviver","urlencoded","extended","parameterLimit","_portHTTP","PORT_HTTP","_portWSS","PORT_WSS","createServer","req","res","next","setHeader","setupAuthRoutes","setupHealthRoutes","setupHomeRoutes","wsUrl","connect","ws","WORKER_INDEX","NODE_APP_INSTANCE","rawData","msg","parse","toString","e","type","handleIncomingTask","err","data","taskId","method","params","userContext","timedOut","timeoutHandle","sendWorkerResponse","managerThis","Object","assign","id_user","user","id_ws","callMethod","call","apply","__spreadArray","__read","result","_b","clearTimeout","err_1","payload","send","getActiveMonitorFunctions","length","setImmediate","getMongoConnection","then","getIsWorkersEnabled","getIsWorkerInstance","getWSList","clients","forEach","push","getWSUserList","getHTTPServer","getCronManager","getMethodManager","getSubscriptionManager","getMonitorManager","getRebootFlag","getWebSocketManager","keepAliveTimeout","headersTimeout","Server","port","verifyClient","info","cb","url","includes","urlParts","split","infoData","headers","origin","token","verify","decoded","Users","findById","fullname","readonly","workerId_1","objectIdHexString","id","activeTasks","maxConcurrency","handleWorkerMessage","filter","w","addWebSocket","createLoggedInUser","unsubscribeWS","socketData","processSocketMessage","now","getTime","readyState","OPEN","duration","asMilliseconds","loggedInLatency","Array","isArray","socketData_1","__values","socketData_1_1","value","handleClientMessage","messageRoute","messageDate","messageId","some","a","roles","groups","views","b","super_admin","subType","pub","subscribe","slice","unsubscribe","serverRes","hasError","offlineUpdates","i","update","shift","updateMessageId","serverResMethod","getLocalLogManager","writeLog","_id","collection","id_document","getBinarySize","route","Logs","insertOne","client","instance","_methods","err_3","getMongoManager","invalidateQueryCache","splice","map","indexOf","dataCopy","msgId","methodName","ack","worker","findAvailableWorker","queueTask","callMethodLocally","err_4","dispatchQueue","item","assignTaskToWorker","candidates","x","sort","task","Math","max","unshift","workerId","messageStr","inflight","find","unsubscribeAll","removeAllListeners","getApp","exports"],"mappings":"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","file":"server-app.js","sourcesContent":["import { createServer, Server } from 'http';\nimport * as express from 'express';\nimport * as bodyParser from 'body-parser';\nimport * as xmlParser from 'express-xml-bodyparser';\nimport * as WebSocket from 'ws';\nimport * as jwt from 'jsonwebtoken';\nimport * as moment from 'moment-timezone';\n\nimport { dateReviver, getBinarySize, objectIdHexString } from './util/common';\nimport { CronManager } from './managers/cron.manager';\nimport { MethodManager } from './managers/method.manager';\nimport { SubscriptionManager } from './managers/subscription.manager';\nimport { MonitorManager, MonitorManagerFunction } from './managers/monitor.manager';\nimport { ServerResponseModel } from './models/server-response.model';\nimport { Logs } from './collections/log.collection';\nimport { Users } from './collections/user.collection';\n\nimport { setupHomeRoutes } from './http/home';\nimport { setupAuthRoutes } from './http/auth';\nimport { setupHealthRoutes } from './http/health';\nimport { MongoNetworkTimeoutError } from 'mongodb';\n\nimport { WebSocketManager } from './managers/websocket.manager';\nimport { ResolveIOServer } from './resolveio-server-app';\n\ninterface WorkerConnection {\n\tid: string;\n\tws: WebSocket;\n\tactiveTasks: number;\n\tmaxConcurrency: number;\n}\n\ninterface TaskQueueItem {\n\ttaskId: string;\n\tmethod: string;\n\tparams: any[];\n\tuserContext?: { id_user?: string; user?: string; id_ws?: string };\n}\n\ninterface InFlightRequest {\n\tws: WebSocket; // the client's WebSocket\n\tmessageId: number; // the ID so the client knows which call this corresponds to\n\tmethod: string;\n}\n\nexport class ResolveIOMainServer {\n\tprivate _app: express.Application;\n\tprivate _serverHTTP: Server;\n\tprivate _portHTTP: string | number;\n\tprivate _serverWSS: WebSocket.Server;\n\tprivate _portWSS: number;\n\tprivate _offlineUpdates = [];\n\tpublic sesMail = false;\n\tprivate standardProgram = false;\n\tprivate publicProgram = false;\n\tprivate _rebootFlag = false;\n\n\tprivate LOGGER = 'ERROR'; //ERROR / DEBUG\n\n\tprivate _websocketManager: WebSocketManager;\n\tprivate _monitorManager: MonitorManager;\n\tprivate _monitorManagerFunction: MonitorManagerFunction;\n\tprivate _subscriptionManager: SubscriptionManager;\n\tprivate _methodManager: MethodManager;\n\tprivate _cronManager: CronManager;\n\tprivate _clientRoutes: string[] = [];\n\n\tprivate _serverStartTime: Date;\n\tprivate _lastErrorMsg: Date = null;\n\n\tprivate _debugMsgRecv = 0;\n\tprivate _debugMsgQueue = 0;\n\n\tprivate _isWorkersEnabled = false;\n\tprivate _isWorkerInstance = false;\n\n\tprivate _safeShutdown = false;\n\n\tprivate _workers: WorkerConnection[] = [];\n\tprivate _taskQueue: TaskQueueItem[] = [];\n\tprivate _inFlightRequests: { [taskId: string]: InFlightRequest } = {};\n\n\tconstructor() {\n\t\tthis._serverStartTime = new Date();\n\t\tthis._lastErrorMsg = null;\n\t\tthis._monitorManager = new MonitorManager();\n\t\tthis._monitorManagerFunction = new MonitorManagerFunction();\n\t}\n\n\tinitServerApp() {\n\t\t// Check for workers and decide what to start\n\t\tthis._isWorkersEnabled = process.env.IS_WORKERS_ENABLED === 'true';\n\t\tthis._isWorkerInstance = process.env.IS_WORKER_INSTANCE === 'true';\n\n\t\tsetInterval(() => {\n\t\t\tif (this._subscriptionManager && this._subscriptionManager.getEnableDebug()) {\n\t\t\t\tconsole.log(new Date(), 'Server App', 'Msg Recv Hits', this._debugMsgRecv);\n\t\t\t\tconsole.log(new Date(), 'Server App', 'Msg Queue Hits', this._debugMsgQueue);\n\t\t\t}\n\n\t\t\tthis._debugMsgQueue = 0;\n\t\t\tthis._debugMsgRecv = 0;\n\t\t}, 60000);\n\n\t\tprocess.on('unhandledRejection', async (error, rej) => {\n\t\t\t// Condition to filter out the MongoError with code 48 (NamespaceExists)\n\t\t\tif (error && error['name'] === 'MongoError' && error['code'] === 48) {\n\t\t\t\treturn; // Simply return without doing anything further\n\t\t\t}\n\n\t\t\t// if (error && error['name'] === 'MongoServerError') {\n\t\t\t// \treturn; // Simply return without doing anything further\n\t\t\t// }\n\n\t\t\tconsole.error(new Date(), 'Unhandled Rejection at Promise', [error, rej]);\n\t\t\t\n\t\t\tlet diffTimeSec = moment().diff(this._serverStartTime, 'seconds');\n\n\t\t\t// If this is a MongoNetworkTimeoutError, handle it specifically\n\t\t\tif (error && (error['name'] === 'MongoNetworkTimeoutError' || error instanceof MongoNetworkTimeoutError)) {\n\t\t\t\tif (diffTimeSec > 60 && !this._lastErrorMsg) {\n\t\t\t\t\tthis._lastErrorMsg = new Date();\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tthis._lastErrorMsg = null;\n\t\t\t\t\t}, 60000);\n\n\t\t\t\t\t// Sending email notification (using your existing method)\n\t\t\t\t\tawait this._methodManager.sendEmail('dev@resolveio.com', 'SERVER - MongoNetworkTimeoutError - Quitting NodeJS - ' + ResolveIOServer.getServerConfig()['CLIENT_NAME'], JSON.stringify({\n\t\t\t\t\t\tname: error['name'],\n\t\t\t\t\t\tmessage: error['message'],\n\t\t\t\t\t\tstack: error['stack']\n\t\t\t\t\t}, null, 2));\n\n\t\t\t\t\t// Exiting the process\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (error && error['name'] === 'MongoError' && error['message'] === 'not master') {\n\t\t\t\tif (diffTimeSec > 60 && !this._lastErrorMsg) {\n\t\t\t\t\tthis._lastErrorMsg = new Date();\n\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tthis._lastErrorMsg = null;\n\t\t\t\t\t}, 60000);\n\n\t\t\t\t\tawait this._methodManager.sendEmail('dev@resolveio.com', 'SERVER - Unhandled Rejection - Quitting NodeJS - ' + ResolveIOServer.getServerConfig()['CLIENT_NAME'], JSON.stringify([error['name'], error['message'], error['stack']], null, 2));\n\t\t\t\t}\n\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t\telse if (error && error['name'] === 'MongoError' && error['message'] === 'not master and slaveOk=false') {\n\t\t\t\tif (diffTimeSec > 60 && !this._lastErrorMsg) {\n\t\t\t\t\tthis._lastErrorMsg = new Date();\n\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tthis._lastErrorMsg = null;\n\t\t\t\t\t}, 60000);\n\n\t\t\t\t\tawait this._methodManager.sendEmail('dev@resolveio.com', 'SERVER - Unhandled Rejection - Quitting NodeJS - ' + ResolveIOServer.getServerConfig()['CLIENT_NAME'], JSON.stringify([error['name'], error['message'], error['stack']], null, 2));\n\t\t\t\t}\n\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t\telse if (error) {\n\t\t\t\tif (error['name'] !== 'StatusError' && error['message'] !== '') {\n\t\t\t\t\tif (diffTimeSec > 60 && !this._lastErrorMsg) {\n\t\t\t\t\t\tthis._lastErrorMsg = new Date();\n\n\t\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\t\tthis._lastErrorMsg = null;\n\t\t\t\t\t\t}, 60000);\n\n\t\t\t\t\t\tthis._methodManager.sendEmail('dev@resolveio.com', 'SERVER - Unhandled Rejection - ' + ResolveIOServer.getServerConfig()['CLIENT_NAME'], JSON.stringify([error['name'], error['message'], error['stack']], null, 2));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tprocess.on('uncaughtException', async error => {\n\t\t\tconsole.error(error, 'Uncaught Exception thrown');\n\n\t\t\tlet diffTimeSec = moment().diff(this._serverStartTime, 'seconds');\n\n\t\t\tif (diffTimeSec > 60 && !this._lastErrorMsg) {\n\t\t\t\tthis._lastErrorMsg = new Date();\n\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tthis._lastErrorMsg = null;\n\t\t\t\t}, 60000);\n\t\t\t\t\n\t\t\t\tawait this._methodManager.sendEmail('dev@resolveio.com', 'SERVER - Unhandled Exception - ' + ResolveIOServer.getServerConfig()['CLIENT_NAME'], JSON.stringify([error['name'], error['message'], error['stack']], null, 2));\n\t\t\t}\n\t\t});\n\n\t\t//PM2 wants to reboot/restart\n\t\tprocess.on('SIGINT', () => {\n\t\t\tthis._rebootFlag = true;\n\t\t\tif (this._serverHTTP) {\n\t\t\t\tthis._serverHTTP.close();\n\t\t\t}\n\t\t\tthis.safeShutdown();\n\t\t});\n\n\t\tprocess.on('SIGTERM', () => {\n\t\t\tthis._rebootFlag = true;\n\t\t\tif (this._serverHTTP) {\n\t\t\t\tthis._serverHTTP.close();\n\t\t\t}\n\t\t\tthis.safeShutdown();\n\t\t});\n\n\t\tprocess.on('SIGQUIT', () => {\n\t\t\tthis._rebootFlag = true;\n\t\t\tif (this._serverHTTP) {\n\t\t\t\tthis._serverHTTP.close();\n\t\t\t}\n\t\t\tthis.safeShutdown();\n\t\t});\n\n\t\tif (this.LOGGER === 'DEBUG') {\n\t\t\tconsole.log('Starting ResolveIO Server');\n\t\t}\n\n\t\tif (this._isWorkersEnabled) {\n\t\t\tif (this._isWorkerInstance) {\n\t\t\t\tconsole.log('Running as a Worker instance');\n\t\t\t\tthis._methodManager = new MethodManager(this._monitorManagerFunction, this._isWorkersEnabled, this._isWorkerInstance);\n\t\t\t\tthis._cronManager = new CronManager();\n\t\t\t\tthis.startWorkerInstance();\n\t\t\t}\n\t\t\telse {\n\t\t\t\tconsole.log('Running as a Server instance');\n\t\t\t\tthis._websocketManager = new WebSocketManager(this);\n\t\t\t\tthis.startServerInstance();\n\t\t\t\tthis._methodManager = new MethodManager(this._monitorManagerFunction, this._isWorkersEnabled, this._isWorkerInstance);\n\t\t\t\tthis._subscriptionManager = new SubscriptionManager(this._serverWSS, ResolveIOServer.getServerConfig(), this._monitorManagerFunction);\n\t\t\t\tthis.listen();\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tconsole.log('Running with Workers Disabled');\n\t\t\tthis._websocketManager = new WebSocketManager(this);\n\t\t\tthis.startServerInstance();\n\t\t\tthis._methodManager = new MethodManager(this._monitorManagerFunction, this._isWorkersEnabled, this._isWorkerInstance);\n\t\t\tthis._subscriptionManager = new SubscriptionManager(this._serverWSS, ResolveIOServer.getServerConfig(), this._monitorManagerFunction);\n\t\t\tthis._cronManager = new CronManager();\n\t\t\tthis.listen();\n\t\t}\n\t}\n\n\tprivate startServerInstance() {\n\t\t// Start express app\n\t\tthis._app = express();\n\n\t\tthis._app.use(bodyParser.json({limit: '50mb', reviver: dateReviver}));\n\t\tthis._app.use(bodyParser.urlencoded({limit: '50mb', extended: true, parameterLimit: 1000000 }));\n\t\tthis._app.use(xmlParser());\n\t\t\n\t\t// Set port\n\t\tthis._portHTTP = process.env.PORT_HTTP || ResolveIOServer.getServerConfig()['PORT_HTTP'] || 8080;\n\t\tthis._portWSS = process.env.PORT_WSS || ResolveIOServer.getServerConfig()['PORT_WSS'] || 8081;\n\n\t\tif (this.LOGGER === 'DEBUG') {\n\t\t\tconsole.log('Setup ports');\n\t\t}\n\n\t\t// Create http server and websock server\n\t\tthis.createServer();\n\n\t\tif (this.LOGGER === 'DEBUG') {\n\t\t\tconsole.log('Create server');\n\t\t}\n\n\t\t// Set CORS\n\t\tthis._app.use(function (req, res, next) {\n\t\t\tres.setHeader('Access-Control-Allow-Origin', '*');\n\t\t\tres.setHeader('Access-Control-Allow-Methods', 'GET, POST');\n\t\t\tres.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');\n\t\t\tres.setHeader('Access-Control-Allow-Credentials', 'false');\n\t\t\tnext();\n\t\t});\n\n\t\tif (this.LOGGER === 'DEBUG') {\n\t\t\tconsole.log('Setup cors');\n\t\t}\n\n\t\t// Set up http login route\n\t\tsetupAuthRoutes(this, this._app, ResolveIOServer.getServerConfig());\n\t\tsetupHealthRoutes(this._app, ResolveIOServer.getServerConfig());\n\n\t\tif (ResolveIOServer.getServerConfig()['CLIENT_NAME'] === 'ResolveIO' || this.standardProgram) {\n\t\t\tsetupHomeRoutes(this, this._app, ResolveIOServer.getServerConfig());\n\t\t}\n\n\t\tif (this.LOGGER === 'DEBUG') {\n\t\t\tconsole.log('Setup express routes');\n\t\t}\n\t}\n\n\tprivate async startWorkerInstance() {\n\t\tconsole.log(new Date(), 'Worker instance started, connecting to main server via WebSocket...');\n\n\t\tlet wsUrl = ResolveIOServer.getServerConfig()['SERVER_URL'] + '/websocket?workerToken=' + ResolveIOServer.getServerConfig()['WORKER_TOKEN'];\n\n\t\tconst connect = () => {\n\t\t\tconst ws = new WebSocket(wsUrl);\n\n\t\t\tws.on('open', () => {\n\t\t\t\tconsole.log(new Date(), 'Connected to main server as worker', process.env.WORKER_INDEX, process.env.NODE_APP_INSTANCE);\n\t\t\t});\n\n\t\t\tws.on('message', async (rawData) => {\n\t\t\t\tlet msg: any;\n\t\t\t\ttry {\n\t\t\t\t\tmsg = JSON.parse(rawData.toString(), dateReviver);\n\t\t\t\t}\n\t\t\t\tcatch (e) {\n\t\t\t\t\tconsole.error('Worker parse error', e);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// We expect: { type: 'task', taskId, method, params, userContext? }\n\t\t\t\tif (msg.type === 'task') {\n\t\t\t\t\tthis.handleIncomingTask(ws, msg);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tws.on('close', () => {\n\t\t\t\tconsole.log(new Date(), 'Disconnected from main server. Reconnecting in 5s...');\n\t\t\t\tsetTimeout(connect, 5000);\n\t\t\t});\n\n\t\t\tws.on('error', (err) => {\n\t\t\t\tconsole.error(new Date(), 'Worker WS error:', err);\n\t\t\t\tws.close();\n\t\t\t});\n\t\t};\n\n\t\tconnect();\n\t}\n\n\tprivate async handleIncomingTask(ws: WebSocket, data: any) {\n\t\tlet { taskId, method, params, userContext } = data;\n\t\tif (!taskId || !method) {\n\t\t\tconsole.log('Invalid task message received', data);\n\t\t\treturn;\n\t\t}\n\n\t\tlet timedOut = false;\n\t\tlet timeoutHandle = setTimeout(() => {\n\t\t\ttimedOut = true;\n\t\t\tconsole.error('Worker timed out on task:', taskId);\n\n\t\t\tthis.sendWorkerResponse(ws, {\n\t\t\t\ttype: 'taskComplete',\n\t\t\t\ttaskId,\n\t\t\t\terror: true,\n\t\t\t\tmessage: 'Task timed out'\n\t\t\t});\n\t\t}, 120000);\n\n\t\ttry {\n\t\t\tlet managerThis = Object.assign({}, this._methodManager, MethodManager.prototype, {\n\t\t\t\tid_user: userContext?.id_user || '',\n\t\t\t\tuser: userContext?.user || '',\n\t\t\t\tid_ws: userContext?.id_ws || ''\n\t\t\t});\n\n\t\t\tlet result = await this._methodManager.callMethod.call(managerThis, method, ...params);\n\n\t\t\tif (!timedOut) {\n\t\t\t\tclearTimeout(timeoutHandle);\n\t\t\t\tthis.sendWorkerResponse(ws, {\n\t\t\t\t\ttype: 'taskComplete',\n\t\t\t\t\ttaskId,\n\t\t\t\t\terror: false,\n\t\t\t\t\tresult\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\tcatch (err) {\n\t\t\tif (!timedOut) {\n\t\t\t\tclearTimeout(timeoutHandle);\n\t\t\t\tconsole.error('Worker failed task:', taskId, err);\n\t\t\t\tthis.sendWorkerResponse(ws, {\n\t\t\t\t\ttype: 'taskComplete',\n\t\t\t\t\ttaskId,\n\t\t\t\t\terror: true,\n\t\t\t\t\tmessage: err.message || 'Unknown error'\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate sendWorkerResponse(ws: WebSocket, payload: any) {\n\t\ttry {\n\t\t\tws.send(JSON.stringify(payload));\n\t\t}\n\t\tcatch (err) {\n\t\t\tconsole.error('Failed to send worker response:', err);\n\t\t}\n\t}\n\n\tprivate safeShutdown() {\n\t\tif (!this._safeShutdown) {\n\t\t\tconsole.log(new Date(), 'Safe Shutdown Command Received');\n\t\t}\n\n\t\tif (\n\t\t\t!this._monitorManagerFunction.getActiveMonitorFunctions().length\n\t\t\t&& !this._offlineUpdates.length\n\t\t) {\n\t\t\tif (ResolveIOServer.getMongoConnection()) {\n\t\t\t\tResolveIOServer.getMongoConnection().close(false).then(() => {\n\t\t\t\t\tconsole.log(new Date(), 'Safe Exit Complete, Process Exit');\n\t\t\t\t\tprocess.exit(0);\n\t\t\t\t}, () => { process.exit(1); });\n\t\t\t}\n\t\t\telse {\n\t\t\t\tprocess.exit(0);\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tif (!this._safeShutdown) {\n\t\t\t\tthis._safeShutdown = true;\n\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tthis._safeShutdown = false;\n\t\t\t\t}, 1000);\n\n\t\t\t\tconsole.log(new Date(), 'Safe Exit In Progress', \n\t\t\t\t\tthis._monitorManagerFunction.getActiveMonitorFunctions().length,\n\t\t\t\t\tthis._offlineUpdates.length\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tsetImmediate(() => {\n\t\t\t\tthis.safeShutdown();\n\t\t\t});\n\t\t}\n\t}\n\n\tgetIsWorkersEnabled() {\n\t\treturn this._isWorkersEnabled;\n\t}\n\n\tgetIsWorkerInstance() {\n\t\treturn this._isWorkerInstance;\n\t}\n\n\tpublic getWSList() {\n\t\tlet res = [];\n\t\tthis._serverWSS.clients.forEach((ws: WebSocket) => {\n\t\t\tres.push(ws['id_socket']);\n\t\t});\n\t\treturn res;\n\t}\n\n\tpublic getWSUserList() {\n\t\tlet res = [];\n\t\tthis._serverWSS.clients.forEach((ws: WebSocket) => {\n\t\t\tres.push(ws['id_user']);\n\t\t});\n\t\treturn res;\n\t}\n\n\tpublic getHTTPServer() {\n\t\treturn this._serverHTTP;\n\t}\n\n\tpublic getCronManager() {\n\t\treturn this._cronManager;\n\t}\n\n\tpublic getMethodManager() {\n\t\treturn this._methodManager;\n\t}\n\n\tpublic getSubscriptionManager() {\n\t\treturn this._subscriptionManager;\n\t}\n\n\tpublic getMonitorManager() {\n\t\treturn this._monitorManager;\n\t}\n\n\tpublic getRebootFlag() {\n\t\treturn this._rebootFlag;\n\t}\n\n\tpublic getWebSocketManager(): WebSocketManager {\n\t\treturn this._websocketManager;\n\t}\n\n\tprivate createServer(): void {\n\t\tthis._serverHTTP = createServer(this._app);\n\t\tthis._serverHTTP.keepAliveTimeout = 65000;\n\t\tthis._serverHTTP.headersTimeout = 66000;\n\n\t\tthis._serverWSS = new WebSocket.Server({\n\t\t\tport: this._portWSS,\n\t\t\tverifyClient: this.publicProgram ? null : async (info, cb) => {\n\t\t\t\tif (this._rebootFlag) {\n\t\t\t\t\tcb(false, 409, 'Unable To Process');\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tif (this.LOGGER === 'DEBUG') {\n\t\t\t\t\t\tconsole.log('Verify Client', info, cb);\n\t\t\t\t\t}\n\n\t\t\t\t\t// If it's a worker, we might skip token checks or do a simple check:\n\t\t\t\t\tif (info.req.url && info.req.url.includes('workerToken=')) {\n\t\t\t\t\t\tlet urlParts = info.req.url.split('workerToken='); \n\t\t\t\t\t\tlet workerToken = urlParts[1] || '';\n\n\t\t\t\t\t\tif (workerToken === ResolveIOServer.getServerConfig()['WORKER_TOKEN']) {\n\t\t\t\t\t\t\tcb(true);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tcb(false, 401, 'Unauthorized');\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tlet infoData = (<string>info.req.headers['sec-websocket-protocol']).split(/,/);\n\n\t\t\t\t\tif (\n\t\t\t\t\t\tinfo.origin !== ResolveIOServer.getServerConfig()['ROOT_URL']\n\t\t\t\t\t\t&& info.origin !== ResolveIOServer.getServerConfig()['SEC_ROOT_URL']\n\t\t\t\t\t\t&& info.origin !== ResolveIOServer.getServerConfig()['RESOLVEIO_URL']\n\t\t\t\t\t\t&& info.origin !== ResolveIOServer.getServerConfig()['RESOLVEIO_SECONDARY_URL']\n\t\t\t\t\t) {\n\t\t\t\t\t\tcb(false, 401, 'Unauthorized');\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tlet token = infoData[0];\n\t\t\t\t\t\tif (!token) {\n\t\t\t\t\t\t\tcb(false, 401, 'Unauthorized');\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tjwt.verify(token, ResolveIOServer.getServerConfig()['JWT_SECRET'], async (err, decoded) => {\n\t\t\t\t\t\t\t\tif (err) {\n\t\t\t\t\t\t\t\t\tcb(false, 401, 'Unauthorized');\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\t\tinfo.req['id_user'] = decoded['id_user'];\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\tlet user = await Users.findById(decoded['id_user']);\n\t\t\t\t\t\t\t\t\t\tif (user) {\n\t\t\t\t\t\t\t\t\t\t\tinfo.req['user'] = user.fullname;\n\t\t\t\t\t\t\t\t\t\t\tinfo.req['user_readonly'] = user.readonly || false;\n\t\t\t\t\t\t\t\t\t\t\tinfo.req['doc_user'] = user;\n\t\t\t\t\t\t\t\t\t\t\tcb(true);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\t\t\t\tcb(false);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tcatch (err) {\n\t\t\t\t\t\t\t\t\t\tcb(false);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Listen for connections from clients or workers.\n\t */\n\tprivate listen(): void {\n\t\tthis._serverHTTP.listen(this._portHTTP, () => {\n\t\t\tconsole.log('Running server on port %s', this._portHTTP);\n\t\t});\n\n\t\tthis._serverWSS.on('listening', () => {\n\t\t\tconsole.log('Running server on port %s', this._portWSS);\n\t\t});\n\n\t\tthis._serverWSS.on('connection', (ws, req) => {\n\t\t\tif (req.url && req.url.includes('workerToken=')) {\n\t\t\t\t// It's a WORKER\n\t\t\t\tlet workerId = objectIdHexString();\n\t\t\t\tws['id_worker'] = workerId;\n\n\t\t\t\t// For demonstration, let each worker handle up to 2 tasks concurrently\n\t\t\t\tlet maxConcurrency = 2;\n\n\t\t\t\tthis._workers.push({\n\t\t\t\t\tid: workerId,\n\t\t\t\t\tws: ws,\n\t\t\t\t\tactiveTasks: 0,\n\t\t\t\t\tmaxConcurrency: maxConcurrency\n\t\t\t\t});\n\n\t\t\t\tconsole.log(new Date(), 'Worker connected:', workerId);\n\n\t\t\t\tws.on('message', (message: string) => {\n\t\t\t\t\tthis.handleWorkerMessage(workerId, message);\n\t\t\t\t});\n\n\t\t\t\tws.on('close', () => {\n\t\t\t\t\tconsole.log(new Date(), 'Worker disconnected:', workerId);\n\t\t\t\t\tthis._workers = this._workers.filter(w => w.id !== workerId);\n\t\t\t\t});\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// Normal client\n\t\t\t\tws['id_socket'] = objectIdHexString();\n\t\t\t\tws['id_user'] = req['id_user'];\n\t\t\t\tws['user'] = req['user'];\n\t\t\t\tws['user_readonly'] = req['user_readonly'];\n\t\t\t\tws['doc_user'] = req['doc_user'];\n\n\t\t\t\tthis._websocketManager.addWebSocket(ws);\n\n\t\t\t\tthis._subscriptionManager.createLoggedInUser(ws['id_socket']).then(() => {\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tws['pingTime'] = new Date();\n\t\t\t\t\t\tws.send('ping', (error) => {\n\t\t\t\t\t\t\tif (error) {\n\t\t\t\t\t\t\t\tif (this._subscriptionManager.getEnableDebug()) {\n\t\t\t\t\t\t\t\t\tconsole.log(new Date(), 'Server App', 'Error WS Ping');\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tthis.unsubscribeWS(ws);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}, 5000);\n\t\t\t\t});\n\n\t\t\t\tif (this.LOGGER === 'DEBUG') {\n\t\t\t\t\tconsole.log('Connection from user: ' + req['user']);\n\t\t\t\t}\n\t\t\t\n\t\t\t\tws['isAlive'] = true;\n\t\t\t\tws['retryCnt'] = 0;\n\n\t\t\t\tws.on('message', async (message: string) => {\n\t\t\t\t\tthis._debugMsgRecv += 1;\n\t\t\t\t\tlet socketData = [];\n\t\t\t\t\n\t\t\t\t\ttry {\n\t\t\t\t\t\tsocketData = JSON.parse(message, dateReviver);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (e) {\n\t\t\t\t\t\tconsole.log('Error - JSON.parse', message);\n\t\t\t\t\t\tthis._methodManager.sendEmail(\n\t\t\t\t\t\t\t'dev@resolveio.com', \n\t\t\t\t\t\t\t'SERVER - JSON Parse Error - ' + ResolveIOServer.getServerConfig()['CLIENT_NAME'], \n\t\t\t\t\t\t\tJSON.stringify([message, e])\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t// call our existing processSocketMessage\n\t\t\t\t\tthis.processSocketMessage(ws, socketData);\n\t\t\t\t})\n\t\t\t\t.on('end', () => {\n\t\t\t\t\tthis.unsubscribeWS(ws);\n\t\t\t\t})\n\t\t\t\t.on('close', () => {\n\t\t\t\t\tthis.unsubscribeWS(ws);\n\t\t\t\t})\n\t\t\t\t.on('error', error => {\n\t\t\t\t\tthis.unsubscribeWS(ws);\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t\t// Keep alive timer\n\t\tsetInterval(() => {\n\t\t\tthis._serverWSS.clients.forEach((ws: WebSocket) => {\n\t\t\t\tif (ws['pingTime'] && Date.now() - ws['pingTime'].getTime() >= 20000) {\n\t\t\t\t\tif (ws['isAlive'] === false) {\n\t\t\t\t\t\tws['retryCnt']++;\n\t\t\t\t\t\tif (ws['retryCnt'] >= 3) {\n\t\t\t\t\t\t\tthis.unsubscribeWS(ws);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tws['pingTime'] = new Date();\n\t\t\t\t\t\t\tws.send('ping', (error) => {\n\t\t\t\t\t\t\t\tif (error) {\n\t\t\t\t\t\t\t\t\tif (this._subscriptionManager.getEnableDebug()) {\n\t\t\t\t\t\t\t\t\t\tconsole.log(new Date(), 'Server App', 'Error WS Ping');\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tthis.unsubscribeWS(ws);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tws['retryCnt'] = 0;\n\t\t\t\t\t\tws['isAlive'] = false;\n\t\t\t\t\t\tws['pingTime'] = new Date();\n\t\t\t\t\t\tws.send('ping', (error) => {\n\t\t\t\t\t\t\tif (error) {\n\t\t\t\t\t\t\t\tif (this._subscriptionManager.getEnableDebug()) {\n\t\t\t\t\t\t\t\t\tconsole.log(new Date(), 'Server App', 'Error WS Ping');\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tthis.unsubscribeWS(ws);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}, 20000);\n\t}\n\n\tprivate async processSocketMessage(ws: WebSocket, socketData: any) {\n\t\tif (typeof socketData === 'string' && socketData === 'ping') {\n\t\t\tif (ws && ws.readyState === ws.OPEN) {\n\t\t\t\tws.send('pong');\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\telse if (typeof socketData === 'string' && socketData === 'pong') {\n\t\t\tws['isAlive'] = true;\n\t\t\tws['pongTime'] = new Date();\n\t\t\tws['latency'] = moment.duration(moment(ws['pongTime']).diff(ws['pingTime'])).asMilliseconds();\n\t\t\tthis._subscriptionManager.loggedInLatency(ws);\n\t\t\treturn;\n\t\t}\n\n\t\t// If the top level is not an array, let's skip\n\t\tif (!Array.isArray(socketData[0])) {\n\t\t\tconsole.log('Invalid message format (expected array of arrays)', socketData);\n\t\t\treturn;\n\t\t}\n\n\t\t// Handle each sub-message\n\t\tfor (let message of socketData) {\n\t\t\tawait this.handleClientMessage(ws, message);\n\t\t}\n\t}\n\n\tprivate async handleClientMessage(ws: WebSocket, msg: any[]): Promise<void> {\n\t\t// This is basically your old logic from processSocketMessage,\n\t\t// but we'll insert our worker-queue logic for \"method\" calls.\n\n\t\tlet messageRoute = msg[0];\n\t\tlet messageDate = msg[1];\n\t\tlet messageId = msg[2];\n\t\tlet type = msg[3];\n\n\t\tif (!this.publicProgram && this._clientRoutes.some(a => messageRoute.includes(a)) && !ws['doc_user'].roles.groups.some(a => a.views.some(b => messageRoute.includes(b) || b.includes(messageRoute))) && !ws['doc_user'].roles.super_admin) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (type === 'subscription') {\n\t\t\tlet subType = msg[4];\n\t\t\tlet pub = msg[5];\n\n\t\t\tif (subType === 'sub') {\n\t\t\t\tthis._subscriptionManager.subscribe(messageRoute, messageDate, ws, messageId, pub, msg.slice(6));\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthis._subscriptionManager.unsubscribe(messageRoute, messageDate, ws, messageId, pub, msg.slice(6));\n\t\t\t}\n\t\t}\n\t\telse if (!this.publicProgram && type === 'offline') {\n\t\t\tlet serverRes: ServerResponseModel = {\n\t\t\t\tmessageId: messageId,\n\t\t\t\thasError: false,\n\t\t\t\tdata: 'ACK'\n\t\t\t};\n\n\t\t\tif (ws && ws.readyState === ws.OPEN) {\n\t\t\t\tthis._websocketManager.send(ws, serverRes);\n\t\t\t}\n\n\t\t\tthis._offlineUpdates.push(ws);\n\t\t\tlet offlineUpdates = msg[4];\n\n\t\t\tfor (let i = 0; i < offlineUpdates.length; i++) {\n\t\t\t\tlet update = offlineUpdates[i];\n\n\t\t\t\tlet data = update.data;\n\n\t\t\t\tlet updateRoute = data.shift();\n\t\t\t\tlet updateDate = data.shift();\n\t\t\t\tlet updateMessageId = data.shift();\n\t\t\t\tlet updateType = data.shift();\n\t\t\t\tlet method = data.shift();\n\n\t\t\t\tlet serverResMethod: ServerResponseModel = {\n\t\t\t\t\tmessageId: updateMessageId,\n\t\t\t\t\thasError: false,\n\t\t\t\t\tdata: 'ACK'\n\t\t\t\t};\n\n\t\t\t\tif (ws && ws.readyState === ws.OPEN) {\n\t\t\t\t\tthis._websocketManager.send(ws, serverResMethod);\n\t\t\t\t}\n\n\t\t\t\tif (method === 'insertDocument' && data[0] === 'driver-gps') {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tif (method !== 'reportBuilderGetResults' && method !== 'reportBuilderGetDistinctValue' && method !== 'reportBuilderBuildTree' && method !== 'generatePDF' && method !== 'getWOOfflineData' && method !== 'countQuery' && method !== 'countWithQuery' && method !== 'countCollectionWithQuery' && method !== 'find' && method !== 'findOne' && method !== 'findWithOptions' && method !== 'getDrivers' && method !== 'processAirdropDistribution') {\n\t\t\t\t\tif (\n\t\t\t\t\t\tResolveIOServer.getServerConfig()['ROOT_URL'] !== 'https://resolveio.com'\n\t\t\t\t\t&& ResolveIOServer.getServerConfig()['ROOT_URL'] !== 'http://localhost:4200'\n\t\t\t\t\t) {\n\t\t\t\t\t\tResolveIOServer.getLocalLogManager().writeLog({\n\t\t\t\t\t\t\ttype: 'log',\n\t\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\t\t_id: objectIdHexString(),\n\t\t\t\t\t\t\t\ttype: 'client-request',\n\t\t\t\t\t\t\t\tcollection: '',\n\t\t\t\t\t\t\t\tid_document: '',\n\t\t\t\t\t\t\t\tpayload: getBinarySize(JSON.stringify(data)) < 200000 ? JSON.stringify(data, null, 2) : 'Too Big',\n\t\t\t\t\t\t\t\tmethod: method,\n\t\t\t\t\t\t\t\tid_user: ws['id_user'] || '',\n\t\t\t\t\t\t\t\tuser: ws['user'] || '',\n\t\t\t\t\t\t\t\tmessageId: messageId,\n\t\t\t\t\t\t\t\troute: messageRoute\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tLogs.insertOne({\n\t\t\t\t\t\t\t_id: objectIdHexString(),\n\t\t\t\t\t\t\ttype: 'client-request',\n\t\t\t\t\t\t\tcollection: '',\n\t\t\t\t\t\t\tid_document: '',\n\t\t\t\t\t\t\tpayload: getBinarySize(JSON.stringify(data)) < 200000 ? JSON.stringify(data, null, 2) : 'Too Big',\n\t\t\t\t\t\t\tmethod: method,\n\t\t\t\t\t\t\tid_user: ws['id_user'] || '',\n\t\t\t\t\t\t\tuser: ws['user'] || '',\n\t\t\t\t\t\t\tmessageId: messageId,\n\t\t\t\t\t\t\troute: messageRoute,\n\t\t\t\t\t\t\tclient: 'ResolveIO',\n\t\t\t\t\t\t\tinstance: 'backend.resolveio.com'\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (this._methodManager._methods[method]) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait this._methodManager.callMethod.call(Object.assign({}, this._methodManager, MethodManager.prototype, {id_user: ws['id_user'], user: ws['user'], id_ws: ws['id_socket']}), method, ...data);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (err) {\n\t\t\t\t\t\tconsole.log(new Date(), 'Offline Error', JSON.stringify(err, null, 2));\n\t\t\t\t\t}\n\n\t\t\t\t\tif (method === 'updateDocumentOffline' || method === 'updateDocumentPropsOffline') {\n\t\t\t\t\t\tResolveIOServer.getMongoManager().invalidateQueryCache(data[0]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tconsole.log('Offline - Could not find method: ' + method);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis._offlineUpdates.splice(this._offlineUpdates.map(a => a['id_socket']).indexOf(ws['id_socket']), 1);\n\t\t}\n\t\telse {\n\t\t\t// It's presumably a 'method' or something else\n\t\t\tlet dataCopy = [...msg];\n\n\t\t\tlet route = dataCopy.shift();\n\t\t\tlet date = dataCopy.shift();\n\t\t\tlet msgId = dataCopy.shift();\n\t\t\tlet msgType = dataCopy.shift();\n\t\t\t\n\t\t\tif (msgType === 'method') {\n\t\t\t\tlet methodName = dataCopy.shift();\n\n\t\t\t\tif (ws['user_readonly']) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (methodName !== 'reportBuilderGetResults' && methodName !== 'reportBuilderGetDistinctValue' && methodName !== 'reportBuilderBuildTree' && methodName !== 'generatePDF' && methodName !== 'getWOOfflineData' && methodName !== 'countQuery' && methodName !== 'countWithQuery' && methodName !== 'countCollectionWithQuery' && methodName !== 'find' && methodName !== 'findOne' && methodName !== 'findWithOptions' && methodName !== 'getDrivers' && methodName !== 'processAirdropDistribution') {\n\t\t\t\t\tif (\n\t\t\t\t\t\tResolveIOServer.getServerConfig()['ROOT_URL'] !== 'https://resolveio.com'\n\t\t\t\t\t&& ResolveIOServer.getServerConfig()['ROOT_URL'] !== 'http://localhost:4200'\n\t\t\t\t\t) {\n\t\t\t\t\t\tResolveIOServer.getLocalLogManager().writeLog({\n\t\t\t\t\t\t\ttype: 'log',\n\t\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\t\t_id: objectIdHexString(),\n\t\t\t\t\t\t\t\ttype: 'client-request',\n\t\t\t\t\t\t\t\tcollection: '',\n\t\t\t\t\t\t\t\tid_document: '',\n\t\t\t\t\t\t\t\tpayload: getBinarySize(JSON.stringify(dataCopy)) < 200000 ? JSON.stringify(dataCopy, null, 2) : 'Too Big',\n\t\t\t\t\t\t\t\tmethod: methodName,\n\t\t\t\t\t\t\t\tid_user: ws['id_user'] || '',\n\t\t\t\t\t\t\t\tuser: ws['user'] || '',\n\t\t\t\t\t\t\t\tmessageId: messageId,\n\t\t\t\t\t\t\t\troute: messageRoute\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tLogs.insertOne({\n\t\t\t\t\t\t\t_id: objectIdHexString(),\n\t\t\t\t\t\t\ttype: 'client-request',\n\t\t\t\t\t\t\tcollection: '',\n\t\t\t\t\t\t\tid_document: '',\n\t\t\t\t\t\t\tpayload: getBinarySize(JSON.stringify(dataCopy)) < 200000 ? JSON.stringify(dataCopy, null, 2) : 'Too Big',\n\t\t\t\t\t\t\tmethod: methodName,\n\t\t\t\t\t\t\tid_user: ws['id_user'] || '',\n\t\t\t\t\t\t\tuser: ws['user'] || '',\n\t\t\t\t\t\t\tmessageId: messageId,\n\t\t\t\t\t\t\troute: messageRoute,\n\t\t\t\t\t\t\tclient: 'ResolveIO',\n\t\t\t\t\t\t\tinstance: 'backend.resolveio.com'\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Immediately ACK\n\t\t\t\tlet ack: ServerResponseModel = {\n\t\t\t\t\tmessageId: msgId,\n\t\t\t\t\thasError: false,\n\t\t\t\t\tdata: 'ACK'\n\t\t\t\t};\n\t\t\t\tif (ws && ws.readyState === ws.OPEN) {\n\t\t\t\t\tthis._websocketManager.send(ws, ack);\n\t\t\t\t}\n\n\t\t\t\t// Check if we can offload to a worker\n\t\t\t\tlet worker = this.findAvailableWorker();\n\t\t\t\tif (this._isWorkersEnabled && \n\t\t\t\t\tworker && \n\t\t\t\t\tmethodName !== 'insertSubscriptionLog' && \n\t\t\t\t\tmethodName !== 'countQuery' &&\n\t\t\t\t\tmethodName !== 'incCounter' && \n\t\t\t\t\tmethodName !== 'supportCreateBillingUser' &&\n\t\t\t\t\tmethodName !== 'find' &&\n\t\t\t\t\tmethodName !== 'insertDocument' &&\n\t\t\t\t\tmethodName !== 'countWithQuery' &&\n\t\t\t\t\tmethodName !== 'findOne' &&\n\t\t\t\t\tmethodName !== 'updateDocumentProps' &&\n\t\t\t\t\tmethodName !== 'findWithOptions' &&\n\t\t\t\t\tmethodName !== 'getSignedUrl' &&\n\t\t\t\t\tmethodName !== 'updateDocument' &&\n\t\t\t\t\tmethodName !== 'insertErrorLog' &&\n\t\t\t\t\tmethodName !== 'getSignedUrls' &&\n\t\t\t\t\tmethodName !== 'removeDocument' &&\n\t\t\t\t\tmethodName !== 'getSignedUrlWithId' &&\n\t\t\t\t\tmethodName !== 'incorrectUser' &&\n\t\t\t\t\tmethodName !== 'reloadWS' &&\n\t\t\t\t\tmethodName !== 'reconnectWS' &&\n\t\t\t\t\tmethodName !== 'disconnectWS'\n\t\t\t\t) {\n\t\t\t\t\t// Offload to a worker\n\t\t\t\t\tlet taskId = 'task-' + objectIdHexString();\n\n\t\t\t\t\t// Store correlation so when worker finishes, we can respond\n\t\t\t\t\tthis._inFlightRequests[taskId] = {\n\t\t\t\t\t\tws,\n\t\t\t\t\t\tmessageId: msgId,\n\t\t\t\t\t\tmethod: methodName\n\t\t\t\t\t};\n\n\t\t\t\t\tthis.queueTask(taskId, methodName, dataCopy, {\n\t\t\t\t\t\tid_user: ws['id_user'],\n\t\t\t\t\t\tuser: ws['user'],\n\t\t\t\t\t\tid_ws: ws['id_socket']\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\t// No worker available: do method locally\n\t\t\t\t\tthis.callMethodLocally(ws, msgId, methodName, dataCopy);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * callMethodLocally is your old approach for invoking the method in-process.\n\t */\n\tprivate async callMethodLocally(ws: WebSocket, messageId: number, method: string, params: any[]) {\n\t\tlet serverRes: ServerResponseModel = {\n\t\t\tmessageId: messageId,\n\t\t\thasError: false,\n\t\t\tdata: null\n\t\t};\n\n\t\ttry {\n\t\t\t// You can keep your logging code (LogMethodLatencies, Logs.insertOne, etc.)\n\t\t\tlet result = await this._methodManager.callMethod.call(\n\t\t\t\tObject.assign({}, this._methodManager, MethodManager.prototype, {\n\t\t\t\t\tid_user: ws['id_user'],\n\t\t\t\t\tuser: ws['user'],\n\t\t\t\t\tid_ws: ws['id_socket']\n\t\t\t\t}),\n\t\t\t\tmethod,\n\t\t\t\t...params\n\t\t\t);\n\n\t\t\tserverRes.data = result;\n\t\t}\n\t\tcatch (err) {\n\t\t\tserverRes.hasError = true;\n\t\t\tserverRes.data = err.message || 'Unknown error';\n\t\t}\n\n\t\tif (ws && ws.readyState === ws.OPEN) {\n\t\t\tthis._websocketManager.send(ws, serverRes);\n\t\t}\n\t}\n\n\t/**\n\t * Add a new task to our in-memory queue and try to dispatch.\n\t */\n\tprivate queueTask(taskId: string, method: string, params: any[], userContext?: { id_user?: string; user?: string; id_ws?: string }) {\n\t\tthis._taskQueue.push({\n\t\t\ttaskId,\n\t\t\tmethod,\n\t\t\tparams,\n\t\t\tuserContext\n\t\t});\n\t\tthis.dispatchQueue();\n\t}\n\n\t/**\n\t * The main loop that assigns tasks from _taskQueue to any worker that has capacity.\n\t */\n\tprivate dispatchQueue() {\n\t\tif (!this._taskQueue.length) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Try to assign tasks while we have them\n\t\tfor (let i = 0; i < 9999; i++) {\n\t\t\tlet item = this._taskQueue[0];\n\t\t\tif (!item) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tlet w = this.findAvailableWorker();\n\t\t\tif (!w) {\n\t\t\t\tbreak; // no worker can take more tasks\n\t\t\t}\n\n\t\t\t// Remove from queue\n\t\t\tthis._taskQueue.shift();\n\t\t\tthis.assignTaskToWorker(w, item);\n\t\t}\n\t}\n\n\t/**\n\t * Returns the worker with the fewest activeTasks that is under maxConcurrency. Or null if none.\n\t */\n\tprivate findAvailableWorker(): WorkerConnection | null {\n\t\tlet candidates = this._workers.filter(x => x.activeTasks < x.maxConcurrency);\n\t\tif (!candidates.length) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Sort by how busy they are\n\t\tcandidates.sort((a, b) => a.activeTasks - b.activeTasks);\n\t\treturn candidates[0];\n\t}\n\n\tprivate assignTaskToWorker(worker: WorkerConnection, task: TaskQueueItem) {\n\t\tworker.activeTasks++;\n\n\t\tlet payload = {\n\t\t\ttype: 'task',\n\t\t\ttaskId: task.taskId,\n\t\t\tmethod: task.method,\n\t\t\tparams: task.params,\n\t\t\tuserContext: task.userContext\n\t\t};\n\n\t\ttry {\n\t\t\tworker.ws.send(JSON.stringify(payload));\n\t\t\tconsole.log('Assigned task', task.taskId, 'to worker', worker.id);\n\t\t}\n\t\tcatch (err) {\n\t\t\tconsole.error('Failed to send task to worker:', err);\n\t\t\tworker.activeTasks = Math.max(0, worker.activeTasks - 1);\n\t\t\t// Put task back at front\n\t\t\tthis._taskQueue.unshift(task);\n\t\t}\n\t}\n\n\t/**\n\t * Handle messages coming back from a worker (like 'taskComplete').\n\t */\n\tprivate handleWorkerMessage(workerId: string, messageStr: string) {\n\t\tlet data: any;\n\t\ttry {\n\t\t\tdata = JSON.parse(messageStr, dateReviver);\n\t\t}\n\t\tcatch (err) {\n\t\t\tconsole.error('Failed to parse worker message:', messageStr);\n\t\t\treturn;\n\t\t}\n\n\t\tif (data.type === 'taskComplete') {\n\t\t\tlet w = this._workers.find(x => x.id === workerId);\n\t\t\tif (!w) {\n\t\t\t\tconsole.error('Unknown worker for taskComplete:', workerId);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tw.activeTasks = Math.max(0, w.activeTasks - 1);\n\n\t\t\tlet { taskId, error, message, result } = data;\n\n\t\t\t// Look up original request\n\t\t\tlet inflight = this._inFlightRequests[taskId];\n\t\t\tif (!inflight) {\n\t\t\t\tconsole.error('No in-flight request found for task:', taskId);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tdelete this._inFlightRequests[taskId];\n\n\t\t\t\t// Send the final response to the client\n\t\t\t\tlet res: ServerResponseModel = {\n\t\t\t\t\tmessageId: inflight.messageId,\n\t\t\t\t\thasError: false,\n\t\t\t\t\tdata: result\n\t\t\t\t};\n\n\t\t\t\tif (error) {\n\t\t\t\t\tres.hasError = true;\n\t\t\t\t\tres.data = message;\n\t\t\t\t}\n\n\t\t\t\tif (inflight.ws && inflight.ws.readyState === inflight.ws.OPEN) {\n\t\t\t\t\tthis._websocketManager.send(inflight.ws, res);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Try to dispatch more from the queue\n\t\t\tthis.dispatchQueue();\n\t\t}\n\t}\n\n\t/**\n\t * Cleanly remove a client from the subscription manager, etc.\n\t */\n\tpublic unsubscribeWS(ws: WebSocket) {\n\t\tif (this._subscriptionManager && this._subscriptionManager.getEnableDebug()) {\n\t\t\tconsole.log(new Date(), 'Server App', 'Unsub WS', ws['user'], ws['id_socket']);\n\t\t}\n\t\tthis._subscriptionManager.unsubscribeAll(ws);\n\t\tws.removeAllListeners();\n\t\tws = null;\n\t}\n\n\tpublic getApp() {\n\t\treturn this._app;\n\t}\n\n\tpublic getServerConfig() {\n\t\treturn ResolveIOServer.getServerConfig();\n\t}\n}"]}
|
|
1
|
+
{"version":3,"sources":["../../src/server-app.ts"],"names":["http_1","require","express","bodyParser","xmlParser","WebSocket","jwt","moment","common_1","cron_manager_1","method_manager_1","subscription_manager_1","monitor_manager_1","log_collection_1","user_collection_1","home_1","auth_1","health_1","mongodb_1","websocket_manager_1","resolveio_server_app_1","ResolveIOMainServer","this","_offlineUpdates","sesMail","standardProgram","publicProgram","_rebootFlag","LOGGER","_clientRoutes","_lastErrorMsg","_debugMsgRecv","_debugMsgQueue","_isWorkersEnabled","_isWorkerInstance","_safeShutdown","_workers","_taskQueue","_inFlightRequests","_serverStartTime","Date","_monitorManager","MonitorManager","_monitorManagerFunction","MonitorManagerFunction","prototype","initServerApp","_this","process","env","IS_WORKERS_ENABLED","IS_WORKER_INSTANCE","setInterval","_subscriptionManager","getEnableDebug","console","log","on","error","rej","__awaiter","diffTimeSec","diff","MongoNetworkTimeoutError","setTimeout","_methodManager","sendEmail","ResolveIOServer","getServerConfig","JSON","stringify","name","message","stack","_a","sent","exit","_serverHTTP","close","safeShutdown","MethodManager","_cronManager","CronManager","startWorkerInstance","_websocketManager","WebSocketManager","startServerInstance","SubscriptionManager","_serverWSS","listen","_app","use","json","limit","reviver","dateReviver","urlencoded","extended","parameterLimit","_portHTTP","PORT_HTTP","_portWSS","PORT_WSS","createServer","req","res","next","setHeader","setupAuthRoutes","setupHealthRoutes","setupHomeRoutes","wsUrl","connect","ws","lastComm","interval","readyState","OPEN","ping","WORKER_INDEX","NODE_APP_INSTANCE","pong","rawData","msg","parse","toString","e","type","handleIncomingTask","clearInterval","err","data","taskId","method","params","userContext","timedOut","timeoutHandle","sendWorkerResponse","managerThis","Object","assign","id_user","user","id_ws","callMethod","call","apply","__spreadArray","__read","result","_b","clearTimeout","err_1","payload","send","getActiveMonitorFunctions","length","setImmediate","getMongoConnection","then","getIsWorkersEnabled","getIsWorkerInstance","getWSList","clients","forEach","push","getWSUserList","getHTTPServer","getCronManager","getMethodManager","getSubscriptionManager","getMonitorManager","getRebootFlag","getWebSocketManager","keepAliveTimeout","headersTimeout","Server","port","verifyClient","info","cb","url","includes","urlParts","split","infoData","headers","origin","token","verify","decoded","Users","findById","fullname","readonly","workerId_1","lastComm_1","interval_1","objectIdHexString","id","activeTasks","maxConcurrency","handleWorkerMessage","filter","w","addWebSocket","createLoggedInUser","unsubscribeWS","socketData","processSocketMessage","now","getTime","duration","asMilliseconds","loggedInLatency","Array","isArray","socketData_1","__values","socketData_1_1","value","handleClientMessage","messageRoute","messageDate","messageId","some","a","roles","groups","views","b","super_admin","subType","pub","subscribe","slice","unsubscribe","serverRes","hasError","offlineUpdates","i","update","shift","updateMessageId","serverResMethod","getLocalLogManager","writeLog","_id","collection","id_document","getBinarySize","route","Logs","insertOne","client","instance","_methods","err_3","getMongoManager","invalidateQueryCache","splice","map","indexOf","dataCopy","msgId","methodName","ack","worker","findAvailableWorker","queueTask","callMethodLocally","err_4","dispatchQueue","item","assignTaskToWorker","candidates","x","sort","task","Math","max","unshift","workerId","messageStr","inflight","find","unsubscribeAll","removeAllListeners","getApp","exports"],"mappings":"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","file":"server-app.js","sourcesContent":["import { createServer, Server } from 'http';\nimport * as express from 'express';\nimport * as bodyParser from 'body-parser';\nimport * as xmlParser from 'express-xml-bodyparser';\nimport * as WebSocket from 'ws';\nimport * as jwt from 'jsonwebtoken';\nimport * as moment from 'moment-timezone';\n\nimport { dateReviver, getBinarySize, objectIdHexString } from './util/common';\nimport { CronManager } from './managers/cron.manager';\nimport { MethodManager } from './managers/method.manager';\nimport { SubscriptionManager } from './managers/subscription.manager';\nimport { MonitorManager, MonitorManagerFunction } from './managers/monitor.manager';\nimport { ServerResponseModel } from './models/server-response.model';\nimport { Logs } from './collections/log.collection';\nimport { Users } from './collections/user.collection';\n\nimport { setupHomeRoutes } from './http/home';\nimport { setupAuthRoutes } from './http/auth';\nimport { setupHealthRoutes } from './http/health';\nimport { MongoNetworkTimeoutError } from 'mongodb';\n\nimport { WebSocketManager } from './managers/websocket.manager';\nimport { ResolveIOServer } from './resolveio-server-app';\n\ninterface WorkerConnection {\n\tid: string;\n\tws: WebSocket;\n\tactiveTasks: number;\n\tmaxConcurrency: number;\n}\n\ninterface TaskQueueItem {\n\ttaskId: string;\n\tmethod: string;\n\tparams: any[];\n\tuserContext?: { id_user?: string; user?: string; id_ws?: string };\n}\n\ninterface InFlightRequest {\n\tws: WebSocket; // the client's WebSocket\n\tmessageId: number; // the ID so the client knows which call this corresponds to\n\tmethod: string;\n}\n\nexport class ResolveIOMainServer {\n\tprivate _app: express.Application;\n\tprivate _serverHTTP: Server;\n\tprivate _portHTTP: string | number;\n\tprivate _serverWSS: WebSocket.Server;\n\tprivate _portWSS: number;\n\tprivate _offlineUpdates = [];\n\tpublic sesMail = false;\n\tprivate standardProgram = false;\n\tprivate publicProgram = false;\n\tprivate _rebootFlag = false;\n\n\tprivate LOGGER = 'ERROR'; //ERROR / DEBUG\n\n\tprivate _websocketManager: WebSocketManager;\n\tprivate _monitorManager: MonitorManager;\n\tprivate _monitorManagerFunction: MonitorManagerFunction;\n\tprivate _subscriptionManager: SubscriptionManager;\n\tprivate _methodManager: MethodManager;\n\tprivate _cronManager: CronManager;\n\tprivate _clientRoutes: string[] = [];\n\n\tprivate _serverStartTime: Date;\n\tprivate _lastErrorMsg: Date = null;\n\n\tprivate _debugMsgRecv = 0;\n\tprivate _debugMsgQueue = 0;\n\n\tprivate _isWorkersEnabled = false;\n\tprivate _isWorkerInstance = false;\n\n\tprivate _safeShutdown = false;\n\n\tprivate _workers: WorkerConnection[] = [];\n\tprivate _taskQueue: TaskQueueItem[] = [];\n\tprivate _inFlightRequests: { [taskId: string]: InFlightRequest } = {};\n\n\tconstructor() {\n\t\tthis._serverStartTime = new Date();\n\t\tthis._lastErrorMsg = null;\n\t\tthis._monitorManager = new MonitorManager();\n\t\tthis._monitorManagerFunction = new MonitorManagerFunction();\n\t}\n\n\tinitServerApp() {\n\t\t// Check for workers and decide what to start\n\t\tthis._isWorkersEnabled = process.env.IS_WORKERS_ENABLED === 'true';\n\t\tthis._isWorkerInstance = process.env.IS_WORKER_INSTANCE === 'true';\n\n\t\tsetInterval(() => {\n\t\t\tif (this._subscriptionManager && this._subscriptionManager.getEnableDebug()) {\n\t\t\t\tconsole.log(new Date(), 'Server App', 'Msg Recv Hits', this._debugMsgRecv);\n\t\t\t\tconsole.log(new Date(), 'Server App', 'Msg Queue Hits', this._debugMsgQueue);\n\t\t\t}\n\n\t\t\tthis._debugMsgQueue = 0;\n\t\t\tthis._debugMsgRecv = 0;\n\t\t}, 60000);\n\n\t\tprocess.on('unhandledRejection', async (error, rej) => {\n\t\t\t// Condition to filter out the MongoError with code 48 (NamespaceExists)\n\t\t\tif (error && error['name'] === 'MongoError' && error['code'] === 48) {\n\t\t\t\treturn; // Simply return without doing anything further\n\t\t\t}\n\n\t\t\t// if (error && error['name'] === 'MongoServerError') {\n\t\t\t// \treturn; // Simply return without doing anything further\n\t\t\t// }\n\n\t\t\tconsole.error(new Date(), 'Unhandled Rejection at Promise', [error, rej]);\n\t\t\t\n\t\t\tlet diffTimeSec = moment().diff(this._serverStartTime, 'seconds');\n\n\t\t\t// If this is a MongoNetworkTimeoutError, handle it specifically\n\t\t\tif (error && (error['name'] === 'MongoNetworkTimeoutError' || error instanceof MongoNetworkTimeoutError)) {\n\t\t\t\tif (diffTimeSec > 60 && !this._lastErrorMsg) {\n\t\t\t\t\tthis._lastErrorMsg = new Date();\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tthis._lastErrorMsg = null;\n\t\t\t\t\t}, 60000);\n\n\t\t\t\t\t// Sending email notification (using your existing method)\n\t\t\t\t\tawait this._methodManager.sendEmail('dev@resolveio.com', 'SERVER - MongoNetworkTimeoutError - Quitting NodeJS - ' + ResolveIOServer.getServerConfig()['CLIENT_NAME'], JSON.stringify({\n\t\t\t\t\t\tname: error['name'],\n\t\t\t\t\t\tmessage: error['message'],\n\t\t\t\t\t\tstack: error['stack']\n\t\t\t\t\t}, null, 2));\n\n\t\t\t\t\t// Exiting the process\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (error && error['name'] === 'MongoError' && error['message'] === 'not master') {\n\t\t\t\tif (diffTimeSec > 60 && !this._lastErrorMsg) {\n\t\t\t\t\tthis._lastErrorMsg = new Date();\n\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tthis._lastErrorMsg = null;\n\t\t\t\t\t}, 60000);\n\n\t\t\t\t\tawait this._methodManager.sendEmail('dev@resolveio.com', 'SERVER - Unhandled Rejection - Quitting NodeJS - ' + ResolveIOServer.getServerConfig()['CLIENT_NAME'], JSON.stringify([error['name'], error['message'], error['stack']], null, 2));\n\t\t\t\t}\n\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t\telse if (error && error['name'] === 'MongoError' && error['message'] === 'not master and slaveOk=false') {\n\t\t\t\tif (diffTimeSec > 60 && !this._lastErrorMsg) {\n\t\t\t\t\tthis._lastErrorMsg = new Date();\n\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tthis._lastErrorMsg = null;\n\t\t\t\t\t}, 60000);\n\n\t\t\t\t\tawait this._methodManager.sendEmail('dev@resolveio.com', 'SERVER - Unhandled Rejection - Quitting NodeJS - ' + ResolveIOServer.getServerConfig()['CLIENT_NAME'], JSON.stringify([error['name'], error['message'], error['stack']], null, 2));\n\t\t\t\t}\n\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t\telse if (error) {\n\t\t\t\tif (error['name'] !== 'StatusError' && error['message'] !== '') {\n\t\t\t\t\tif (diffTimeSec > 60 && !this._lastErrorMsg) {\n\t\t\t\t\t\tthis._lastErrorMsg = new Date();\n\n\t\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\t\tthis._lastErrorMsg = null;\n\t\t\t\t\t\t}, 60000);\n\n\t\t\t\t\t\tthis._methodManager.sendEmail('dev@resolveio.com', 'SERVER - Unhandled Rejection - ' + ResolveIOServer.getServerConfig()['CLIENT_NAME'], JSON.stringify([error['name'], error['message'], error['stack']], null, 2));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tprocess.on('uncaughtException', async error => {\n\t\t\tconsole.error(error, 'Uncaught Exception thrown');\n\n\t\t\tlet diffTimeSec = moment().diff(this._serverStartTime, 'seconds');\n\n\t\t\tif (diffTimeSec > 60 && !this._lastErrorMsg) {\n\t\t\t\tthis._lastErrorMsg = new Date();\n\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tthis._lastErrorMsg = null;\n\t\t\t\t}, 60000);\n\t\t\t\t\n\t\t\t\tawait this._methodManager.sendEmail('dev@resolveio.com', 'SERVER - Unhandled Exception - ' + ResolveIOServer.getServerConfig()['CLIENT_NAME'], JSON.stringify([error['name'], error['message'], error['stack']], null, 2));\n\t\t\t}\n\t\t});\n\n\t\t//PM2 wants to reboot/restart\n\t\tprocess.on('SIGINT', () => {\n\t\t\tthis._rebootFlag = true;\n\t\t\tif (this._serverHTTP) {\n\t\t\t\tthis._serverHTTP.close();\n\t\t\t}\n\t\t\tthis.safeShutdown();\n\t\t});\n\n\t\tprocess.on('SIGTERM', () => {\n\t\t\tthis._rebootFlag = true;\n\t\t\tif (this._serverHTTP) {\n\t\t\t\tthis._serverHTTP.close();\n\t\t\t}\n\t\t\tthis.safeShutdown();\n\t\t});\n\n\t\tprocess.on('SIGQUIT', () => {\n\t\t\tthis._rebootFlag = true;\n\t\t\tif (this._serverHTTP) {\n\t\t\t\tthis._serverHTTP.close();\n\t\t\t}\n\t\t\tthis.safeShutdown();\n\t\t});\n\n\t\tif (this.LOGGER === 'DEBUG') {\n\t\t\tconsole.log('Starting ResolveIO Server');\n\t\t}\n\n\t\tif (this._isWorkersEnabled) {\n\t\t\tif (this._isWorkerInstance) {\n\t\t\t\tconsole.log('Running as a Worker instance');\n\t\t\t\tthis._methodManager = new MethodManager(this._monitorManagerFunction, this._isWorkersEnabled, this._isWorkerInstance);\n\t\t\t\tthis._cronManager = new CronManager();\n\t\t\t\tthis.startWorkerInstance();\n\t\t\t}\n\t\t\telse {\n\t\t\t\tconsole.log('Running as a Server instance');\n\t\t\t\tthis._websocketManager = new WebSocketManager(this);\n\t\t\t\tthis.startServerInstance();\n\t\t\t\tthis._methodManager = new MethodManager(this._monitorManagerFunction, this._isWorkersEnabled, this._isWorkerInstance);\n\t\t\t\tthis._subscriptionManager = new SubscriptionManager(this._serverWSS, ResolveIOServer.getServerConfig(), this._monitorManagerFunction);\n\t\t\t\tthis.listen();\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tconsole.log('Running with Workers Disabled');\n\t\t\tthis._websocketManager = new WebSocketManager(this);\n\t\t\tthis.startServerInstance();\n\t\t\tthis._methodManager = new MethodManager(this._monitorManagerFunction, this._isWorkersEnabled, this._isWorkerInstance);\n\t\t\tthis._subscriptionManager = new SubscriptionManager(this._serverWSS, ResolveIOServer.getServerConfig(), this._monitorManagerFunction);\n\t\t\tthis._cronManager = new CronManager();\n\t\t\tthis.listen();\n\t\t}\n\t}\n\n\tprivate startServerInstance() {\n\t\t// Start express app\n\t\tthis._app = express();\n\n\t\tthis._app.use(bodyParser.json({limit: '50mb', reviver: dateReviver}));\n\t\tthis._app.use(bodyParser.urlencoded({limit: '50mb', extended: true, parameterLimit: 1000000 }));\n\t\tthis._app.use(xmlParser());\n\t\t\n\t\t// Set port\n\t\tthis._portHTTP = process.env.PORT_HTTP || ResolveIOServer.getServerConfig()['PORT_HTTP'] || 8080;\n\t\tthis._portWSS = process.env.PORT_WSS || ResolveIOServer.getServerConfig()['PORT_WSS'] || 8081;\n\n\t\tif (this.LOGGER === 'DEBUG') {\n\t\t\tconsole.log('Setup ports');\n\t\t}\n\n\t\t// Create http server and websock server\n\t\tthis.createServer();\n\n\t\tif (this.LOGGER === 'DEBUG') {\n\t\t\tconsole.log('Create server');\n\t\t}\n\n\t\t// Set CORS\n\t\tthis._app.use(function (req, res, next) {\n\t\t\tres.setHeader('Access-Control-Allow-Origin', '*');\n\t\t\tres.setHeader('Access-Control-Allow-Methods', 'GET, POST');\n\t\t\tres.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');\n\t\t\tres.setHeader('Access-Control-Allow-Credentials', 'false');\n\t\t\tnext();\n\t\t});\n\n\t\tif (this.LOGGER === 'DEBUG') {\n\t\t\tconsole.log('Setup cors');\n\t\t}\n\n\t\t// Set up http login route\n\t\tsetupAuthRoutes(this, this._app, ResolveIOServer.getServerConfig());\n\t\tsetupHealthRoutes(this._app, ResolveIOServer.getServerConfig());\n\n\t\tif (ResolveIOServer.getServerConfig()['CLIENT_NAME'] === 'ResolveIO' || this.standardProgram) {\n\t\t\tsetupHomeRoutes(this, this._app, ResolveIOServer.getServerConfig());\n\t\t}\n\n\t\tif (this.LOGGER === 'DEBUG') {\n\t\t\tconsole.log('Setup express routes');\n\t\t}\n\t}\n\n\tprivate async startWorkerInstance() {\n\t\tconsole.log(new Date(), 'Worker instance started, connecting to main server via WebSocket...');\n\n\t\tlet wsUrl = ResolveIOServer.getServerConfig()['SERVER_URL'] + '/websocket?workerToken=' + ResolveIOServer.getServerConfig()['WORKER_TOKEN'];\n\n\t\tconst connect = () => {\n\t\t\tconst ws = new WebSocket(wsUrl);\n\n\t\t\tlet lastComm = null;\n\n\t\t\tif (ws && ws.readyState === ws.OPEN) {\n\t\t\t\tws.ping();\n\t\t\t}\n\n\t\t\tlet interval = setInterval(() => {\n\t\t\t\tif (!lastComm) {\n\t\t\t\t\tws.close();\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tlastComm = null;\n\n\t\t\t\t\tif (ws && ws.readyState === ws.OPEN) {\n\t\t\t\t\t\tws.ping();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}, 15000);\n\n\t\t\tws.on('open', () => {\n\t\t\t\tconsole.log(new Date(), 'Connected to main server as worker', process.env.WORKER_INDEX, process.env.NODE_APP_INSTANCE);\n\t\t\t});\n\n\t\t\tws.on('ping', () => {\n\t\t\t\tws.pong(); // manually respond\n\t\t\t});\n\n\t\t\tws.on('pong', () => {\n\t\t\t\tlastComm = new Date();\n\t\t\t});\n\n\t\t\tws.on('message', async (rawData) => {\n\t\t\t\tlet msg: any;\n\t\t\t\ttry {\n\t\t\t\t\tmsg = JSON.parse(rawData.toString(), dateReviver);\n\t\t\t\t}\n\t\t\t\tcatch (e) {\n\t\t\t\t\tconsole.error('Worker parse error', e);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// We expect: { type: 'task', taskId, method, params, userContext? }\n\t\t\t\tif (msg.type === 'task') {\n\t\t\t\t\tthis.handleIncomingTask(ws, msg);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tws.on('close', () => {\n\t\t\t\tconsole.log(new Date(), 'Disconnected from main server. Reconnecting in 5s...');\n\t\t\t\tsetTimeout(connect, 5000);\n\t\t\t\tclearInterval(interval);\n\t\t\t});\n\n\t\t\tws.on('error', (err) => {\n\t\t\t\tconsole.error(new Date(), 'Worker WS error:', err);\n\t\t\t\tws.close();\n\t\t\t});\n\t\t};\n\n\t\tconnect();\n\t}\n\n\tprivate async handleIncomingTask(ws: WebSocket, data: any) {\n\t\tlet { taskId, method, params, userContext } = data;\n\t\tif (!taskId || !method) {\n\t\t\tconsole.log('Invalid task message received', data);\n\t\t\treturn;\n\t\t}\n\n\t\tlet timedOut = false;\n\t\tlet timeoutHandle = setTimeout(() => {\n\t\t\ttimedOut = true;\n\t\t\tconsole.error('Worker timed out on task:', taskId);\n\n\t\t\tthis.sendWorkerResponse(ws, {\n\t\t\t\ttype: 'taskComplete',\n\t\t\t\ttaskId,\n\t\t\t\terror: true,\n\t\t\t\tmessage: 'Task timed out'\n\t\t\t});\n\t\t}, 120000);\n\n\t\ttry {\n\t\t\tlet managerThis = Object.assign({}, this._methodManager, MethodManager.prototype, {\n\t\t\t\tid_user: userContext?.id_user || '',\n\t\t\t\tuser: userContext?.user || '',\n\t\t\t\tid_ws: userContext?.id_ws || ''\n\t\t\t});\n\n\t\t\tlet result = await this._methodManager.callMethod.call(managerThis, method, ...params);\n\n\t\t\tif (!timedOut) {\n\t\t\t\tclearTimeout(timeoutHandle);\n\t\t\t\tthis.sendWorkerResponse(ws, {\n\t\t\t\t\ttype: 'taskComplete',\n\t\t\t\t\ttaskId,\n\t\t\t\t\terror: false,\n\t\t\t\t\tresult\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\tcatch (err) {\n\t\t\tif (!timedOut) {\n\t\t\t\tclearTimeout(timeoutHandle);\n\t\t\t\tconsole.error('Worker failed task:', taskId, err);\n\t\t\t\tthis.sendWorkerResponse(ws, {\n\t\t\t\t\ttype: 'taskComplete',\n\t\t\t\t\ttaskId,\n\t\t\t\t\terror: true,\n\t\t\t\t\tmessage: err.message || 'Unknown error'\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate sendWorkerResponse(ws: WebSocket, payload: any) {\n\t\ttry {\n\t\t\tws.send(JSON.stringify(payload));\n\t\t}\n\t\tcatch (err) {\n\t\t\tconsole.error('Failed to send worker response:', err);\n\t\t}\n\t}\n\n\tprivate safeShutdown() {\n\t\tif (!this._safeShutdown) {\n\t\t\tconsole.log(new Date(), 'Safe Shutdown Command Received');\n\t\t}\n\n\t\tif (\n\t\t\t!this._monitorManagerFunction.getActiveMonitorFunctions().length\n\t\t\t&& !this._offlineUpdates.length\n\t\t) {\n\t\t\tif (ResolveIOServer.getMongoConnection()) {\n\t\t\t\tResolveIOServer.getMongoConnection().close(false).then(() => {\n\t\t\t\t\tconsole.log(new Date(), 'Safe Exit Complete, Process Exit');\n\t\t\t\t\tprocess.exit(0);\n\t\t\t\t}, () => { process.exit(1); });\n\t\t\t}\n\t\t\telse {\n\t\t\t\tprocess.exit(0);\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tif (!this._safeShutdown) {\n\t\t\t\tthis._safeShutdown = true;\n\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tthis._safeShutdown = false;\n\t\t\t\t}, 1000);\n\n\t\t\t\tconsole.log(new Date(), 'Safe Exit In Progress', \n\t\t\t\t\tthis._monitorManagerFunction.getActiveMonitorFunctions().length,\n\t\t\t\t\tthis._offlineUpdates.length\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tsetImmediate(() => {\n\t\t\t\tthis.safeShutdown();\n\t\t\t});\n\t\t}\n\t}\n\n\tgetIsWorkersEnabled() {\n\t\treturn this._isWorkersEnabled;\n\t}\n\n\tgetIsWorkerInstance() {\n\t\treturn this._isWorkerInstance;\n\t}\n\n\tpublic getWSList() {\n\t\tlet res = [];\n\t\tthis._serverWSS.clients.forEach((ws: WebSocket) => {\n\t\t\tres.push(ws['id_socket']);\n\t\t});\n\t\treturn res;\n\t}\n\n\tpublic getWSUserList() {\n\t\tlet res = [];\n\t\tthis._serverWSS.clients.forEach((ws: WebSocket) => {\n\t\t\tres.push(ws['id_user']);\n\t\t});\n\t\treturn res;\n\t}\n\n\tpublic getHTTPServer() {\n\t\treturn this._serverHTTP;\n\t}\n\n\tpublic getCronManager() {\n\t\treturn this._cronManager;\n\t}\n\n\tpublic getMethodManager() {\n\t\treturn this._methodManager;\n\t}\n\n\tpublic getSubscriptionManager() {\n\t\treturn this._subscriptionManager;\n\t}\n\n\tpublic getMonitorManager() {\n\t\treturn this._monitorManager;\n\t}\n\n\tpublic getRebootFlag() {\n\t\treturn this._rebootFlag;\n\t}\n\n\tpublic getWebSocketManager(): WebSocketManager {\n\t\treturn this._websocketManager;\n\t}\n\n\tprivate createServer(): void {\n\t\tthis._serverHTTP = createServer(this._app);\n\t\tthis._serverHTTP.keepAliveTimeout = 65000;\n\t\tthis._serverHTTP.headersTimeout = 66000;\n\n\t\tthis._serverWSS = new WebSocket.Server({\n\t\t\tport: this._portWSS,\n\t\t\tverifyClient: this.publicProgram ? null : async (info, cb) => {\n\t\t\t\tif (this._rebootFlag) {\n\t\t\t\t\tcb(false, 409, 'Unable To Process');\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tif (this.LOGGER === 'DEBUG') {\n\t\t\t\t\t\tconsole.log('Verify Client', info, cb);\n\t\t\t\t\t}\n\n\t\t\t\t\t// If it's a worker, we might skip token checks or do a simple check:\n\t\t\t\t\tif (info.req.url && info.req.url.includes('workerToken=')) {\n\t\t\t\t\t\tlet urlParts = info.req.url.split('workerToken='); \n\t\t\t\t\t\tlet workerToken = urlParts[1] || '';\n\n\t\t\t\t\t\tif (workerToken === ResolveIOServer.getServerConfig()['WORKER_TOKEN']) {\n\t\t\t\t\t\t\tcb(true);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tcb(false, 401, 'Unauthorized');\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tlet infoData = (<string>info.req.headers['sec-websocket-protocol']).split(/,/);\n\n\t\t\t\t\tif (\n\t\t\t\t\t\tinfo.origin !== ResolveIOServer.getServerConfig()['ROOT_URL']\n\t\t\t\t\t\t&& info.origin !== ResolveIOServer.getServerConfig()['SEC_ROOT_URL']\n\t\t\t\t\t\t&& info.origin !== ResolveIOServer.getServerConfig()['RESOLVEIO_URL']\n\t\t\t\t\t\t&& info.origin !== ResolveIOServer.getServerConfig()['RESOLVEIO_SECONDARY_URL']\n\t\t\t\t\t) {\n\t\t\t\t\t\tcb(false, 401, 'Unauthorized');\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tlet token = infoData[0];\n\t\t\t\t\t\tif (!token) {\n\t\t\t\t\t\t\tcb(false, 401, 'Unauthorized');\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tjwt.verify(token, ResolveIOServer.getServerConfig()['JWT_SECRET'], async (err, decoded) => {\n\t\t\t\t\t\t\t\tif (err) {\n\t\t\t\t\t\t\t\t\tcb(false, 401, 'Unauthorized');\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\t\tinfo.req['id_user'] = decoded['id_user'];\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\tlet user = await Users.findById(decoded['id_user']);\n\t\t\t\t\t\t\t\t\t\tif (user) {\n\t\t\t\t\t\t\t\t\t\t\tinfo.req['user'] = user.fullname;\n\t\t\t\t\t\t\t\t\t\t\tinfo.req['user_readonly'] = user.readonly || false;\n\t\t\t\t\t\t\t\t\t\t\tinfo.req['doc_user'] = user;\n\t\t\t\t\t\t\t\t\t\t\tcb(true);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\t\t\t\tcb(false);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tcatch (err) {\n\t\t\t\t\t\t\t\t\t\tcb(false);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Listen for connections from clients or workers.\n\t */\n\tprivate listen(): void {\n\t\tthis._serverHTTP.listen(this._portHTTP, () => {\n\t\t\tconsole.log('Running server on port %s', this._portHTTP);\n\t\t});\n\n\t\tthis._serverWSS.on('listening', () => {\n\t\t\tconsole.log('Running server on port %s', this._portWSS);\n\t\t});\n\n\t\tthis._serverWSS.on('connection', (ws, req) => {\n\t\t\tif (req.url && req.url.includes('workerToken=')) {\n\t\t\t\t// It's a WORKER\n\t\t\t\tlet workerId = objectIdHexString();\n\t\t\t\tws['id_worker'] = workerId;\n\n\t\t\t\t// For demonstration, let each worker handle up to 2 tasks concurrently\n\t\t\t\tlet maxConcurrency = 2;\n\n\t\t\t\tthis._workers.push({\n\t\t\t\t\tid: workerId,\n\t\t\t\t\tws: ws,\n\t\t\t\t\tactiveTasks: 0,\n\t\t\t\t\tmaxConcurrency: maxConcurrency\n\t\t\t\t});\n\n\t\t\t\tlet lastComm = null;\n\n\t\t\t\tif (ws && ws.readyState === ws.OPEN) {\n\t\t\t\t\tws.ping();\n\t\t\t\t}\n\n\t\t\t\tlet interval = setInterval(() => {\n\t\t\t\t\tif (!lastComm) {\n\t\t\t\t\t\tws.close();\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tlastComm = null;\n\t\n\t\t\t\t\t\tif (ws && ws.readyState === ws.OPEN) {\n\t\t\t\t\t\t\tws.ping();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}, 15000);\n\n\t\t\t\tconsole.log(new Date(), 'Worker connected:', workerId);\n\n\t\t\t\tws.on('message', (message: string) => {\n\t\t\t\t\tthis.handleWorkerMessage(workerId, message);\n\t\t\t\t});\n\n\t\t\t\tws.on('ping', () => {\n\t\t\t\t\tws.pong(); // manually respond\n\t\t\t\t});\n\n\t\t\t\tws.on('pong', () => {\n\t\t\t\t\tlastComm = new Date();\n\t\t\t\t});\n\n\t\t\t\tws.on('close', () => {\n\t\t\t\t\tconsole.log(new Date(), 'Worker disconnected:', workerId);\n\t\t\t\t\tthis._workers = this._workers.filter(w => w.id !== workerId);\n\t\t\t\t\tclearInterval(interval);\n\t\t\t\t});\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// Normal client\n\t\t\t\tws['id_socket'] = objectIdHexString();\n\t\t\t\tws['id_user'] = req['id_user'];\n\t\t\t\tws['user'] = req['user'];\n\t\t\t\tws['user_readonly'] = req['user_readonly'];\n\t\t\t\tws['doc_user'] = req['doc_user'];\n\n\t\t\t\tthis._websocketManager.addWebSocket(ws);\n\n\t\t\t\tthis._subscriptionManager.createLoggedInUser(ws['id_socket']).then(() => {\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tws['pingTime'] = new Date();\n\t\t\t\t\t\tws.send('ping', (error) => {\n\t\t\t\t\t\t\tif (error) {\n\t\t\t\t\t\t\t\tif (this._subscriptionManager.getEnableDebug()) {\n\t\t\t\t\t\t\t\t\tconsole.log(new Date(), 'Server App', 'Error WS Ping');\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tthis.unsubscribeWS(ws);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}, 5000);\n\t\t\t\t});\n\n\t\t\t\tif (this.LOGGER === 'DEBUG') {\n\t\t\t\t\tconsole.log('Connection from user: ' + req['user']);\n\t\t\t\t}\n\t\t\t\n\t\t\t\tws['isAlive'] = true;\n\t\t\t\tws['retryCnt'] = 0;\n\n\t\t\t\tws.on('message', async (message: string) => {\n\t\t\t\t\tthis._debugMsgRecv += 1;\n\t\t\t\t\tlet socketData = [];\n\t\t\t\t\n\t\t\t\t\ttry {\n\t\t\t\t\t\tsocketData = JSON.parse(message, dateReviver);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (e) {\n\t\t\t\t\t\tconsole.log('Error - JSON.parse', message);\n\t\t\t\t\t\tthis._methodManager.sendEmail(\n\t\t\t\t\t\t\t'dev@resolveio.com', \n\t\t\t\t\t\t\t'SERVER - JSON Parse Error - ' + ResolveIOServer.getServerConfig()['CLIENT_NAME'], \n\t\t\t\t\t\t\tJSON.stringify([message, e])\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t// call our existing processSocketMessage\n\t\t\t\t\tthis.processSocketMessage(ws, socketData);\n\t\t\t\t})\n\t\t\t\t.on('end', () => {\n\t\t\t\t\tthis.unsubscribeWS(ws);\n\t\t\t\t})\n\t\t\t\t.on('close', () => {\n\t\t\t\t\tthis.unsubscribeWS(ws);\n\t\t\t\t})\n\t\t\t\t.on('error', error => {\n\t\t\t\t\tthis.unsubscribeWS(ws);\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t\t// Keep alive timer\n\t\tsetInterval(() => {\n\t\t\tthis._serverWSS.clients.forEach((ws: WebSocket) => {\n\t\t\t\tif (ws['pingTime'] && Date.now() - ws['pingTime'].getTime() >= 20000) {\n\t\t\t\t\tif (ws['isAlive'] === false) {\n\t\t\t\t\t\tws['retryCnt']++;\n\t\t\t\t\t\tif (ws['retryCnt'] >= 3) {\n\t\t\t\t\t\t\tthis.unsubscribeWS(ws);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tws['pingTime'] = new Date();\n\t\t\t\t\t\t\tws.send('ping', (error) => {\n\t\t\t\t\t\t\t\tif (error) {\n\t\t\t\t\t\t\t\t\tif (this._subscriptionManager.getEnableDebug()) {\n\t\t\t\t\t\t\t\t\t\tconsole.log(new Date(), 'Server App', 'Error WS Ping');\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tthis.unsubscribeWS(ws);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tws['retryCnt'] = 0;\n\t\t\t\t\t\tws['isAlive'] = false;\n\t\t\t\t\t\tws['pingTime'] = new Date();\n\t\t\t\t\t\tws.send('ping', (error) => {\n\t\t\t\t\t\t\tif (error) {\n\t\t\t\t\t\t\t\tif (this._subscriptionManager.getEnableDebug()) {\n\t\t\t\t\t\t\t\t\tconsole.log(new Date(), 'Server App', 'Error WS Ping');\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tthis.unsubscribeWS(ws);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}, 20000);\n\t}\n\n\tprivate async processSocketMessage(ws: WebSocket, socketData: any) {\n\t\tif (typeof socketData === 'string' && socketData === 'ping') {\n\t\t\tif (ws && ws.readyState === ws.OPEN) {\n\t\t\t\tws.send('pong');\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\telse if (typeof socketData === 'string' && socketData === 'pong') {\n\t\t\tws['isAlive'] = true;\n\t\t\tws['pongTime'] = new Date();\n\t\t\tws['latency'] = moment.duration(moment(ws['pongTime']).diff(ws['pingTime'])).asMilliseconds();\n\t\t\tthis._subscriptionManager.loggedInLatency(ws);\n\t\t\treturn;\n\t\t}\n\n\t\t// If the top level is not an array, let's skip\n\t\tif (!Array.isArray(socketData[0])) {\n\t\t\tconsole.log('Invalid message format (expected array of arrays)', socketData);\n\t\t\treturn;\n\t\t}\n\n\t\t// Handle each sub-message\n\t\tfor (let message of socketData) {\n\t\t\tawait this.handleClientMessage(ws, message);\n\t\t}\n\t}\n\n\tprivate async handleClientMessage(ws: WebSocket, msg: any[]): Promise<void> {\n\t\t// This is basically your old logic from processSocketMessage,\n\t\t// but we'll insert our worker-queue logic for \"method\" calls.\n\n\t\tlet messageRoute = msg[0];\n\t\tlet messageDate = msg[1];\n\t\tlet messageId = msg[2];\n\t\tlet type = msg[3];\n\n\t\tif (!this.publicProgram && this._clientRoutes.some(a => messageRoute.includes(a)) && !ws['doc_user'].roles.groups.some(a => a.views.some(b => messageRoute.includes(b) || b.includes(messageRoute))) && !ws['doc_user'].roles.super_admin) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (type === 'subscription') {\n\t\t\tlet subType = msg[4];\n\t\t\tlet pub = msg[5];\n\n\t\t\tif (subType === 'sub') {\n\t\t\t\tthis._subscriptionManager.subscribe(messageRoute, messageDate, ws, messageId, pub, msg.slice(6));\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthis._subscriptionManager.unsubscribe(messageRoute, messageDate, ws, messageId, pub, msg.slice(6));\n\t\t\t}\n\t\t}\n\t\telse if (!this.publicProgram && type === 'offline') {\n\t\t\tlet serverRes: ServerResponseModel = {\n\t\t\t\tmessageId: messageId,\n\t\t\t\thasError: false,\n\t\t\t\tdata: 'ACK'\n\t\t\t};\n\n\t\t\tif (ws && ws.readyState === ws.OPEN) {\n\t\t\t\tthis._websocketManager.send(ws, serverRes);\n\t\t\t}\n\n\t\t\tthis._offlineUpdates.push(ws);\n\t\t\tlet offlineUpdates = msg[4];\n\n\t\t\tfor (let i = 0; i < offlineUpdates.length; i++) {\n\t\t\t\tlet update = offlineUpdates[i];\n\n\t\t\t\tlet data = update.data;\n\n\t\t\t\tlet updateRoute = data.shift();\n\t\t\t\tlet updateDate = data.shift();\n\t\t\t\tlet updateMessageId = data.shift();\n\t\t\t\tlet updateType = data.shift();\n\t\t\t\tlet method = data.shift();\n\n\t\t\t\tlet serverResMethod: ServerResponseModel = {\n\t\t\t\t\tmessageId: updateMessageId,\n\t\t\t\t\thasError: false,\n\t\t\t\t\tdata: 'ACK'\n\t\t\t\t};\n\n\t\t\t\tif (ws && ws.readyState === ws.OPEN) {\n\t\t\t\t\tthis._websocketManager.send(ws, serverResMethod);\n\t\t\t\t}\n\n\t\t\t\tif (method === 'insertDocument' && data[0] === 'driver-gps') {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tif (method !== 'reportBuilderGetResults' && method !== 'reportBuilderGetDistinctValue' && method !== 'reportBuilderBuildTree' && method !== 'generatePDF' && method !== 'getWOOfflineData' && method !== 'countQuery' && method !== 'countWithQuery' && method !== 'countCollectionWithQuery' && method !== 'find' && method !== 'findOne' && method !== 'findWithOptions' && method !== 'getDrivers' && method !== 'processAirdropDistribution') {\n\t\t\t\t\tif (\n\t\t\t\t\t\tResolveIOServer.getServerConfig()['ROOT_URL'] !== 'https://resolveio.com'\n\t\t\t\t\t&& ResolveIOServer.getServerConfig()['ROOT_URL'] !== 'http://localhost:4200'\n\t\t\t\t\t) {\n\t\t\t\t\t\tResolveIOServer.getLocalLogManager().writeLog({\n\t\t\t\t\t\t\ttype: 'log',\n\t\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\t\t_id: objectIdHexString(),\n\t\t\t\t\t\t\t\ttype: 'client-request',\n\t\t\t\t\t\t\t\tcollection: '',\n\t\t\t\t\t\t\t\tid_document: '',\n\t\t\t\t\t\t\t\tpayload: getBinarySize(JSON.stringify(data)) < 200000 ? JSON.stringify(data, null, 2) : 'Too Big',\n\t\t\t\t\t\t\t\tmethod: method,\n\t\t\t\t\t\t\t\tid_user: ws['id_user'] || '',\n\t\t\t\t\t\t\t\tuser: ws['user'] || '',\n\t\t\t\t\t\t\t\tmessageId: messageId,\n\t\t\t\t\t\t\t\troute: messageRoute\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tLogs.insertOne({\n\t\t\t\t\t\t\t_id: objectIdHexString(),\n\t\t\t\t\t\t\ttype: 'client-request',\n\t\t\t\t\t\t\tcollection: '',\n\t\t\t\t\t\t\tid_document: '',\n\t\t\t\t\t\t\tpayload: getBinarySize(JSON.stringify(data)) < 200000 ? JSON.stringify(data, null, 2) : 'Too Big',\n\t\t\t\t\t\t\tmethod: method,\n\t\t\t\t\t\t\tid_user: ws['id_user'] || '',\n\t\t\t\t\t\t\tuser: ws['user'] || '',\n\t\t\t\t\t\t\tmessageId: messageId,\n\t\t\t\t\t\t\troute: messageRoute,\n\t\t\t\t\t\t\tclient: 'ResolveIO',\n\t\t\t\t\t\t\tinstance: 'backend.resolveio.com'\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (this._methodManager._methods[method]) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait this._methodManager.callMethod.call(Object.assign({}, this._methodManager, MethodManager.prototype, {id_user: ws['id_user'], user: ws['user'], id_ws: ws['id_socket']}), method, ...data);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (err) {\n\t\t\t\t\t\tconsole.log(new Date(), 'Offline Error', JSON.stringify(err, null, 2));\n\t\t\t\t\t}\n\n\t\t\t\t\tif (method === 'updateDocumentOffline' || method === 'updateDocumentPropsOffline') {\n\t\t\t\t\t\tResolveIOServer.getMongoManager().invalidateQueryCache(data[0]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tconsole.log('Offline - Could not find method: ' + method);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis._offlineUpdates.splice(this._offlineUpdates.map(a => a['id_socket']).indexOf(ws['id_socket']), 1);\n\t\t}\n\t\telse {\n\t\t\t// It's presumably a 'method' or something else\n\t\t\tlet dataCopy = [...msg];\n\n\t\t\tlet route = dataCopy.shift();\n\t\t\tlet date = dataCopy.shift();\n\t\t\tlet msgId = dataCopy.shift();\n\t\t\tlet msgType = dataCopy.shift();\n\t\t\t\n\t\t\tif (msgType === 'method') {\n\t\t\t\tlet methodName = dataCopy.shift();\n\n\t\t\t\tif (ws['user_readonly']) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (methodName !== 'reportBuilderGetResults' && methodName !== 'reportBuilderGetDistinctValue' && methodName !== 'reportBuilderBuildTree' && methodName !== 'generatePDF' && methodName !== 'getWOOfflineData' && methodName !== 'countQuery' && methodName !== 'countWithQuery' && methodName !== 'countCollectionWithQuery' && methodName !== 'find' && methodName !== 'findOne' && methodName !== 'findWithOptions' && methodName !== 'getDrivers' && methodName !== 'processAirdropDistribution') {\n\t\t\t\t\tif (\n\t\t\t\t\t\tResolveIOServer.getServerConfig()['ROOT_URL'] !== 'https://resolveio.com'\n\t\t\t\t\t&& ResolveIOServer.getServerConfig()['ROOT_URL'] !== 'http://localhost:4200'\n\t\t\t\t\t) {\n\t\t\t\t\t\tResolveIOServer.getLocalLogManager().writeLog({\n\t\t\t\t\t\t\ttype: 'log',\n\t\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\t\t_id: objectIdHexString(),\n\t\t\t\t\t\t\t\ttype: 'client-request',\n\t\t\t\t\t\t\t\tcollection: '',\n\t\t\t\t\t\t\t\tid_document: '',\n\t\t\t\t\t\t\t\tpayload: getBinarySize(JSON.stringify(dataCopy)) < 200000 ? JSON.stringify(dataCopy, null, 2) : 'Too Big',\n\t\t\t\t\t\t\t\tmethod: methodName,\n\t\t\t\t\t\t\t\tid_user: ws['id_user'] || '',\n\t\t\t\t\t\t\t\tuser: ws['user'] || '',\n\t\t\t\t\t\t\t\tmessageId: messageId,\n\t\t\t\t\t\t\t\troute: messageRoute\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tLogs.insertOne({\n\t\t\t\t\t\t\t_id: objectIdHexString(),\n\t\t\t\t\t\t\ttype: 'client-request',\n\t\t\t\t\t\t\tcollection: '',\n\t\t\t\t\t\t\tid_document: '',\n\t\t\t\t\t\t\tpayload: getBinarySize(JSON.stringify(dataCopy)) < 200000 ? JSON.stringify(dataCopy, null, 2) : 'Too Big',\n\t\t\t\t\t\t\tmethod: methodName,\n\t\t\t\t\t\t\tid_user: ws['id_user'] || '',\n\t\t\t\t\t\t\tuser: ws['user'] || '',\n\t\t\t\t\t\t\tmessageId: messageId,\n\t\t\t\t\t\t\troute: messageRoute,\n\t\t\t\t\t\t\tclient: 'ResolveIO',\n\t\t\t\t\t\t\tinstance: 'backend.resolveio.com'\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Immediately ACK\n\t\t\t\tlet ack: ServerResponseModel = {\n\t\t\t\t\tmessageId: msgId,\n\t\t\t\t\thasError: false,\n\t\t\t\t\tdata: 'ACK'\n\t\t\t\t};\n\t\t\t\tif (ws && ws.readyState === ws.OPEN) {\n\t\t\t\t\tthis._websocketManager.send(ws, ack);\n\t\t\t\t}\n\n\t\t\t\t// Check if we can offload to a worker\n\t\t\t\tlet worker = this.findAvailableWorker();\n\t\t\t\tif (this._isWorkersEnabled && \n\t\t\t\t\tworker && \n\t\t\t\t\tmethodName !== 'insertSubscriptionLog' && \n\t\t\t\t\tmethodName !== 'countQuery' &&\n\t\t\t\t\tmethodName !== 'incCounter' && \n\t\t\t\t\tmethodName !== 'supportCreateBillingUser' &&\n\t\t\t\t\tmethodName !== 'find' &&\n\t\t\t\t\tmethodName !== 'insertDocument' &&\n\t\t\t\t\tmethodName !== 'countWithQuery' &&\n\t\t\t\t\tmethodName !== 'findOne' &&\n\t\t\t\t\tmethodName !== 'updateDocumentProps' &&\n\t\t\t\t\tmethodName !== 'findWithOptions' &&\n\t\t\t\t\tmethodName !== 'getSignedUrl' &&\n\t\t\t\t\tmethodName !== 'updateDocument' &&\n\t\t\t\t\tmethodName !== 'insertErrorLog' &&\n\t\t\t\t\tmethodName !== 'getSignedUrls' &&\n\t\t\t\t\tmethodName !== 'removeDocument' &&\n\t\t\t\t\tmethodName !== 'getSignedUrlWithId' &&\n\t\t\t\t\tmethodName !== 'incorrectUser' &&\n\t\t\t\t\tmethodName !== 'reloadWS' &&\n\t\t\t\t\tmethodName !== 'reconnectWS' &&\n\t\t\t\t\tmethodName !== 'disconnectWS'\n\t\t\t\t) {\n\t\t\t\t\t// Offload to a worker\n\t\t\t\t\tlet taskId = 'task-' + objectIdHexString();\n\n\t\t\t\t\t// Store correlation so when worker finishes, we can respond\n\t\t\t\t\tthis._inFlightRequests[taskId] = {\n\t\t\t\t\t\tws,\n\t\t\t\t\t\tmessageId: msgId,\n\t\t\t\t\t\tmethod: methodName\n\t\t\t\t\t};\n\n\t\t\t\t\tthis.queueTask(taskId, methodName, dataCopy, {\n\t\t\t\t\t\tid_user: ws['id_user'],\n\t\t\t\t\t\tuser: ws['user'],\n\t\t\t\t\t\tid_ws: ws['id_socket']\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\t// No worker available: do method locally\n\t\t\t\t\tthis.callMethodLocally(ws, msgId, methodName, dataCopy);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * callMethodLocally is your old approach for invoking the method in-process.\n\t */\n\tprivate async callMethodLocally(ws: WebSocket, messageId: number, method: string, params: any[]) {\n\t\tlet serverRes: ServerResponseModel = {\n\t\t\tmessageId: messageId,\n\t\t\thasError: false,\n\t\t\tdata: null\n\t\t};\n\n\t\ttry {\n\t\t\t// You can keep your logging code (LogMethodLatencies, Logs.insertOne, etc.)\n\t\t\tlet result = await this._methodManager.callMethod.call(\n\t\t\t\tObject.assign({}, this._methodManager, MethodManager.prototype, {\n\t\t\t\t\tid_user: ws['id_user'],\n\t\t\t\t\tuser: ws['user'],\n\t\t\t\t\tid_ws: ws['id_socket']\n\t\t\t\t}),\n\t\t\t\tmethod,\n\t\t\t\t...params\n\t\t\t);\n\n\t\t\tserverRes.data = result;\n\t\t}\n\t\tcatch (err) {\n\t\t\tserverRes.hasError = true;\n\t\t\tserverRes.data = err.message || 'Unknown error';\n\t\t}\n\n\t\tif (ws && ws.readyState === ws.OPEN) {\n\t\t\tthis._websocketManager.send(ws, serverRes);\n\t\t}\n\t}\n\n\t/**\n\t * Add a new task to our in-memory queue and try to dispatch.\n\t */\n\tprivate queueTask(taskId: string, method: string, params: any[], userContext?: { id_user?: string; user?: string; id_ws?: string }) {\n\t\tthis._taskQueue.push({\n\t\t\ttaskId,\n\t\t\tmethod,\n\t\t\tparams,\n\t\t\tuserContext\n\t\t});\n\t\tthis.dispatchQueue();\n\t}\n\n\t/**\n\t * The main loop that assigns tasks from _taskQueue to any worker that has capacity.\n\t */\n\tprivate dispatchQueue() {\n\t\tif (!this._taskQueue.length) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Try to assign tasks while we have them\n\t\tfor (let i = 0; i < 9999; i++) {\n\t\t\tlet item = this._taskQueue[0];\n\t\t\tif (!item) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tlet w = this.findAvailableWorker();\n\t\t\tif (!w) {\n\t\t\t\tbreak; // no worker can take more tasks\n\t\t\t}\n\n\t\t\t// Remove from queue\n\t\t\tthis._taskQueue.shift();\n\t\t\tthis.assignTaskToWorker(w, item);\n\t\t}\n\t}\n\n\t/**\n\t * Returns the worker with the fewest activeTasks that is under maxConcurrency. Or null if none.\n\t */\n\tprivate findAvailableWorker(): WorkerConnection | null {\n\t\tlet candidates = this._workers.filter(x => x.activeTasks < x.maxConcurrency);\n\t\tif (!candidates.length) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Sort by how busy they are\n\t\tcandidates.sort((a, b) => a.activeTasks - b.activeTasks);\n\t\treturn candidates[0];\n\t}\n\n\tprivate assignTaskToWorker(worker: WorkerConnection, task: TaskQueueItem) {\n\t\tworker.activeTasks++;\n\n\t\tlet payload = {\n\t\t\ttype: 'task',\n\t\t\ttaskId: task.taskId,\n\t\t\tmethod: task.method,\n\t\t\tparams: task.params,\n\t\t\tuserContext: task.userContext\n\t\t};\n\n\t\ttry {\n\t\t\tworker.ws.send(JSON.stringify(payload));\n\t\t\tconsole.log('Assigned task', task.taskId, 'to worker', worker.id);\n\t\t}\n\t\tcatch (err) {\n\t\t\tconsole.error('Failed to send task to worker:', err);\n\t\t\tworker.activeTasks = Math.max(0, worker.activeTasks - 1);\n\t\t\t// Put task back at front\n\t\t\tthis._taskQueue.unshift(task);\n\t\t}\n\t}\n\n\t/**\n\t * Handle messages coming back from a worker (like 'taskComplete').\n\t */\n\tprivate handleWorkerMessage(workerId: string, messageStr: string) {\n\t\tlet data: any;\n\t\ttry {\n\t\t\tdata = JSON.parse(messageStr, dateReviver);\n\t\t}\n\t\tcatch (err) {\n\t\t\tconsole.error('Failed to parse worker message:', messageStr);\n\t\t\treturn;\n\t\t}\n\n\t\tif (data.type === 'taskComplete') {\n\t\t\tlet w = this._workers.find(x => x.id === workerId);\n\t\t\tif (!w) {\n\t\t\t\tconsole.error('Unknown worker for taskComplete:', workerId);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tw.activeTasks = Math.max(0, w.activeTasks - 1);\n\n\t\t\tlet { taskId, error, message, result } = data;\n\n\t\t\t// Look up original request\n\t\t\tlet inflight = this._inFlightRequests[taskId];\n\t\t\tif (!inflight) {\n\t\t\t\tconsole.error('No in-flight request found for task:', taskId);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tdelete this._inFlightRequests[taskId];\n\n\t\t\t\t// Send the final response to the client\n\t\t\t\tlet res: ServerResponseModel = {\n\t\t\t\t\tmessageId: inflight.messageId,\n\t\t\t\t\thasError: false,\n\t\t\t\t\tdata: result\n\t\t\t\t};\n\n\t\t\t\tif (error) {\n\t\t\t\t\tres.hasError = true;\n\t\t\t\t\tres.data = message;\n\t\t\t\t}\n\n\t\t\t\tif (inflight.ws && inflight.ws.readyState === inflight.ws.OPEN) {\n\t\t\t\t\tthis._websocketManager.send(inflight.ws, res);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Try to dispatch more from the queue\n\t\t\tthis.dispatchQueue();\n\t\t}\n\t}\n\n\t/**\n\t * Cleanly remove a client from the subscription manager, etc.\n\t */\n\tpublic unsubscribeWS(ws: WebSocket) {\n\t\tif (this._subscriptionManager && this._subscriptionManager.getEnableDebug()) {\n\t\t\tconsole.log(new Date(), 'Server App', 'Unsub WS', ws['user'], ws['id_socket']);\n\t\t}\n\t\tthis._subscriptionManager.unsubscribeAll(ws);\n\t\tws.removeAllListeners();\n\t\tws = null;\n\t}\n\n\tpublic getApp() {\n\t\treturn this._app;\n\t}\n\n\tpublic getServerConfig() {\n\t\treturn ResolveIOServer.getServerConfig();\n\t}\n}"]}
|