UNPKG

ziron-broker

Version:
1 lines 4.32 kB
"use strict";var __awaiter=this&&this.__awaiter||function(e,t,i,r){return new(i||(i=Promise))((function(o,s){function n(e){try{h(r.next(e))}catch(e){s(e)}}function c(e){try{h(r.throw(e))}catch(e){s(e)}}function h(e){var t;e.done?o(e.value):(t=e.value,t instanceof i?t:new i((function(e){e(t)}))).then(n,c)}h((r=r.apply(e,t||[])).next())}))};Object.defineProperty(exports,"__esModule",{value:!0}),exports.BrokerServer=void 0;const Logger_1=require("./Logger"),ziron_server_1=require("ziron-server"),ziron_client_1=require("ziron-client"),ip_1=require("ip"),Object_1=require("./Object"),Utils_1=require("./Utils"),CLUSTER_VERSION=1;class BrokerServer{get id(){return this.server.id}constructor(e={}){this._options={join:null,logLevel:Logger_1.LogLevel.Everything,port:8888,path:"/"},this.procedures={},this.receivers={},this._options=(0,Object_1.buildOptions)(this._options,e),this._logger=new Logger_1.default(this._options.logLevel);const t=this._options.join||"",i=t.indexOf("@");-1===i?(this._joinSecret="",this._joinUri=t):(this._joinSecret=t.substring(0,i),this._joinUri=t.substring(i+1)),this._options.path=""===this._options.path||"/"===this._options.path?"":this._options.path.startsWith("/")?this._options.path:"/"+this._options.path,this.server=new ziron_server_1.Server({port:this._options.port,pingInterval:4e3,allowClientPublish:!0,socketChannelLimit:null,publishToPublisher:!1}),this._initServer()}isConnectedToState(){var e;return null===(e=this._stateSocket)||void 0===e?void 0:e.isConnected()}listen(){return __awaiter(this,void 0,void 0,(function*(){if(!this.server.isListening())try{this._logger.logBusy("Launching broker server..."),yield this.server.listen(),this._logger.logActive(`Broker server launched successfully on port: ${this._options.port}.`)}catch(e){throw e instanceof ziron_server_1.FailedToListenError&&this._logger.logFailed(`Failed to listen on port: ${this._options.port}. Maybe the port is already in use.`),e}}))}listenAndJoin(){return __awaiter(this,void 0,void 0,(function*(){yield this.listen(),yield this.join()}))}_initServer(){this.server.upgradeMiddleware=e=>{const t=e.attachment;if("object"!=typeof t)throw new ziron_server_1.Block(400,"Invalid attachment structure");if(t.secret!==this._joinSecret)throw new ziron_server_1.Block(403,"Permission denied");if(1!==t.clusterVersion)throw new ziron_server_1.Block(412,"Incompatible cluster versions")},this.server.connectionHandler=e=>((0,ziron_server_1.applyStandaloneProcedures)(e,this.procedures),(0,ziron_server_1.applyStandaloneReceivers)(e,this.receivers),this.id)}join(){return __awaiter(this,void 0,void 0,(function*(){if(!this.server.isListening())throw new Error("The broker needs to listen before joining a cluster.");if(this._stateSocket)throw new Error("Join should only be invoked once. The server will automatically retry to rejoin the cluster in case of disconnection.");let e,t,i=!1;const r=new Promise((i,r)=>{e=i,t=r});let o;this._stateSocket=new ziron_client_1.Socket(this._joinUri,{responseTimeout:3e3,connectTimeout:3e3,autoReconnect:{active:!0,initialDelay:1e3,randomness:1e3,multiplier:1,maxDelay:2e3},handshakeAttachment:{secret:this._joinSecret,clusterVersion:1,node:{id:this.server.id,type:1,ip:(0,ip_1.address)(),port:this._options.port,path:this._options.path}}}),this._stateSocket.on("error",e=>{this._logger.logError("Error in state socket: "+e.stack)});const s=()=>__awaiter(this,void 0,void 0,(function*(){try{yield this._stateSocket.invoke("#join"),this._logger.logInfo(`Broker has ${i?"re":""}joined the cluster.`),i=!0,e()}catch(e){const i=(0,Utils_1.ensureError)(e);if(t(i),"IdAlreadyUsedInClusterError"===i.name?this._logger.logWarning(`Attempt to join the cluster failed, the server-id: "${this.server.id}" already exists in the cluster.`):i.stack&&this._logger.logError(`Attempt to join the cluster failed: ${i.stack}.`),!this._stateSocket.isConnected())return;o=setTimeout(s,2e3)}}));return this._stateSocket.on("disconnect",()=>{this.stateId=void 0}),this._stateSocket.on("connect",e=>{e&&(this.stateId=e),clearTimeout(o),s()}),this._stateSocket.connect().catch(e=>{t(e),this._logger.logError(`Attempt to join the cluster failed: ${e.stack}.`)}),r}))}terminate(){var e;this.server.terminate(),null===(e=this._stateSocket)||void 0===e||e.disconnect()}}exports.BrokerServer=BrokerServer;