ziron-state 6.0.0 → 6.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  import { StateServer } from "./lib/StateServer";
2
2
  import { LogLevel } from "./lib/Logger";
3
- export { StateServer, LogLevel };
3
+ import StateServerOptions from "./lib/StateServerOptions";
4
+ export { StateServer, StateServerOptions, LogLevel };
@@ -1,4 +1,4 @@
1
- import { Socket } from "ziron-server";
1
+ import { Server, Socket } from "ziron-server";
2
2
  import StateServerOptions from "./StateServerOptions";
3
3
  import { StandaloneProcedures } from "ziron-server/dist/lib/Procedure";
4
4
  import { StandaloneReceivers } from "ziron-server/dist/lib/Receiver";
@@ -27,7 +27,13 @@ export declare class StateServer {
27
27
  private _joinedWorkers;
28
28
  private _joinedBrokers;
29
29
  private readonly _logger;
30
- private readonly _server;
30
+ /**
31
+ * @description
32
+ * Use the server object carefully.
33
+ * Never change properties on the server; use it only to access state information.
34
+ * @protected
35
+ */
36
+ protected readonly server: Server;
31
37
  readonly joinToken: string;
32
38
  private _clusterSession;
33
39
  private _scaleTimeout?;
@@ -1 +1 @@
1
- "use strict";var __awaiter=this&&this.__awaiter||function(e,t,r,s){return new(r||(r=Promise))((function(i,o){function n(e){try{d(s.next(e))}catch(e){o(e)}}function a(e){try{d(s.throw(e))}catch(e){o(e)}}function d(e){var t;e.done?i(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t)}))).then(n,a)}d((s=s.apply(e,t||[])).next())}))};Object.defineProperty(exports,"__esModule",{value:!0}),exports.StateServer=void 0;const ziron_server_1=require("ziron-server"),Logger_1=require("./Logger"),Crypto_1=require("./Crypto"),uniqId=require("uniqid"),ip=require("ip"),isIp=require("is-ip"),Object_1=require("./Object"),Errors_1=require("./Errors"),CLUSTER_VERSION=1;class StateServer{constructor(e={}){this._listenCalled=!1,this._options={logLevel:1,secret:Crypto_1.generateSecret().substring(0,32),port:7777,path:"/",scaleDelay:100},this._workerLeader=null,this._joinedWorkers={},this._joinedBrokers={},this._clusterSession=null,this.procedures={},this.receivers={},this._handleWorkerJoin=(e,t,r,s)=>__awaiter(this,void 0,void 0,(function*(){"object"!=typeof t&&(t={});const{shared:i,payload:o}=t;if(this.workerJoinMiddleware)try{yield this.workerJoinMiddleware(e,"object"!=typeof o?{}:o)}catch(e){return s(new Error(e.message||"Join was blocked by the join middleware"))}if(this._isNodeIdInUse(e.node.id))return s(new Errors_1.IdAlreadyUsedInClusterError(e.node.id));0===Object.keys(this._joinedWorkers).length&&this._createClusterSession(i),this._joinedWorkers[e.node.id]=e,e.join("JoinedWorkers"),this._selectWorkerLeader(),r({session:this._clusterSession,brokers:this.getJoinedBrokersState()}),this._logRunningState()})),this._handleWorkerLeave=e=>{delete this._joinedWorkers[e.node.id],e.leave("JoinedWorkers"),this._workerLeader===e&&(this._workerLeader=null,e.node.leader=!1,this._selectWorkerLeader()),0===Object.keys(this._joinedWorkers).length&&this._resetClusterSession(),this._logRunningState()},this._handleBrokerJoin=(e,t,r,s)=>{if(this._isNodeIdInUse(e.node.id))return s(new Errors_1.IdAlreadyUsedInClusterError(e.node.id));this._joinedBrokers[e.node.id]=e,this._scaleOut(),r(),this._logRunningState()},this._handleBrokerLeave=e=>{delete this._joinedBrokers[e.node.id],this._scaleBack(),this._logRunningState()},this._workerLeaderSelectionPromise=Promise.resolve(),this._options=Object_1.buildOptions(this._options,e),this._logger=new Logger_1.default(this._options.logLevel),this._logger.logBusy("Launching state server..."),this.joinToken=this._getJoinToken(),this._server=new ziron_server_1.Server({port:this._options.port,pingInterval:1e3,path:this._options.path}),this._initServer()}listen(){return __awaiter(this,void 0,void 0,(function*(){this._listenCalled||(this._listenCalled=!0,yield this._server.listen(),this._logger.logActive(`State server launched successfully on port: ${this._options.port}.`),this._logRunningState())}))}_logRunningState(){this._logger.logRunningState(Object.values(this._joinedWorkers),Object.values(this._joinedBrokers),this.joinToken)}_getJoinToken(){const e=ip.address(),t=""===this._options.path||"/"===this._options.path?"":this._options.path.startsWith("/")?this._options.path:"/"+this._options.path;return`${this._options.secret?this._options.secret+"@":""}ws://${isIp.v6(e)?`[${e}]`:e}:${this._options.port}${t}`}_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._options.secret)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.socketMiddleware=e=>{const t=e.handshakeAttachment.node;if("object"!=typeof t||0!==t.type&&1!==t.type||"string"!=typeof t.id||"number"!=typeof t.port||"string"!=typeof t.path)throw new ziron_server_1.Block(4005,"Invalid attachment structure");{const r="string"==typeof t.ip&&isIp(t.ip)?t.ip:e.remoteAddress;if(!r)throw new ziron_server_1.Block(4012,"Could not detect node IP address");if(""!==t.path&&!t.path.startsWith("/"))throw new ziron_server_1.Block(4005,"Invalid node path");e.node={id:t.id,type:t.type,ip:r,port:t.port,path:t.path,uri:`ws://${isIp.v6(r)?`[${r}]`:r}:${t.port}${t.path}`,leader:!1}}},this._server.connectionHandler=e=>{const t=e.node.type;e.on("disconnect",0===t?()=>this._handleWorkerLeave(e):()=>this._handleBrokerLeave(e)),ziron_server_1.applyStandaloneProcedures(e,this.procedures),ziron_server_1.applyStandaloneReceivers(e,this.receivers),e.procedures["#leave"]=0===t?(t,r)=>{this._handleWorkerLeave(e),r()}:(t,r)=>{this._handleBrokerLeave(e),r()},e.procedures["#join"]=0===t?(...t)=>this._handleWorkerJoin(e,...t):(...t)=>this._handleBrokerJoin(e,...t)}}_createClusterSession(e){this._clusterSession={id:uniqId(),shared:e}}_resetClusterSession(){this._clusterSession=null}static _getJoinedState(e){return{time:Date.now(),uris:Object.values(e).map(e=>e.node.uri)}}getJoinedBrokersState(){return StateServer._getJoinedState(this._joinedBrokers)}getJoinedWorkersState(){return StateServer._getJoinedState(this._joinedWorkers)}_getRandomWorker(){return Crypto_1.getRandomArrayItem(Object.values(this._joinedWorkers))}_selectWorkerLeader(){this._workerLeaderSelectionPromise=this._workerLeaderSelectionPromise.then(()=>this._selectWorkerLeaderProcess())}_selectWorkerLeaderProcess(){return __awaiter(this,void 0,void 0,(function*(){let e;if(null==this._workerLeader&&void 0!==(e=this._getRandomWorker())){try{yield e.invoke("addLeadership")}catch(e){return yield this._selectWorkerLeaderProcess()}e.node.leader=!0,this._workerLeader=e,this._logRunningState()}}))}_scaleOut(){this._setScaleTimeout(()=>this._updateWorkersBrokerState())}_scaleBack(){this._setScaleTimeout(()=>this._updateWorkersBrokerState())}_setScaleTimeout(e){null!=this._scaleTimeout&&clearTimeout(this._scaleTimeout),this._scaleTimeout=setTimeout(e,this._options.scaleDelay)}_updateWorkersBrokerState(){this._server.transmitToGroup("JoinedWorkers","updateBrokers",this.getJoinedBrokersState())}_isNodeIdInUse(e){return this._joinedWorkers.hasOwnProperty(e)||this._joinedBrokers.hasOwnProperty(e)||e===this._server.id}terminate(){this._workerLeader=null,this._joinedWorkers={},this._joinedBrokers={},this._server.terminate()}}exports.StateServer=StateServer;
1
+ "use strict";var __awaiter=this&&this.__awaiter||function(e,t,r,s){return new(r||(r=Promise))((function(i,o){function n(e){try{d(s.next(e))}catch(e){o(e)}}function a(e){try{d(s.throw(e))}catch(e){o(e)}}function d(e){var t;e.done?i(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t)}))).then(n,a)}d((s=s.apply(e,t||[])).next())}))};Object.defineProperty(exports,"__esModule",{value:!0}),exports.StateServer=void 0;const ziron_server_1=require("ziron-server"),Logger_1=require("./Logger"),Crypto_1=require("./Crypto"),uniqId=require("uniqid"),ip=require("ip"),isIp=require("is-ip"),Object_1=require("./Object"),Errors_1=require("./Errors"),CLUSTER_VERSION=1;class StateServer{constructor(e={}){this._listenCalled=!1,this._options={logLevel:1,secret:Crypto_1.generateSecret().substring(0,32),port:7777,path:"/",scaleDelay:100},this._workerLeader=null,this._joinedWorkers={},this._joinedBrokers={},this._clusterSession=null,this.procedures={},this.receivers={},this._handleWorkerJoin=(e,t,r,s)=>__awaiter(this,void 0,void 0,(function*(){"object"!=typeof t&&(t={});const{shared:i,payload:o}=t;if(this.workerJoinMiddleware)try{yield this.workerJoinMiddleware(e,"object"!=typeof o?{}:o)}catch(e){return s(new Error(e.message||"Join was blocked by the join middleware"))}if(this._isNodeIdInUse(e.node.id))return s(new Errors_1.IdAlreadyUsedInClusterError(e.node.id));0===Object.keys(this._joinedWorkers).length&&this._createClusterSession(i),this._joinedWorkers[e.node.id]=e,e.join("JoinedWorkers"),this._selectWorkerLeader(),r({session:this._clusterSession,brokers:this.getJoinedBrokersState()}),this._logRunningState()})),this._handleWorkerLeave=e=>{delete this._joinedWorkers[e.node.id],e.leave("JoinedWorkers"),this._workerLeader===e&&(this._workerLeader=null,e.node.leader=!1,this._selectWorkerLeader()),0===Object.keys(this._joinedWorkers).length&&this._resetClusterSession(),this._logRunningState()},this._handleBrokerJoin=(e,t,r,s)=>{if(this._isNodeIdInUse(e.node.id))return s(new Errors_1.IdAlreadyUsedInClusterError(e.node.id));this._joinedBrokers[e.node.id]=e,this._scaleOut(),r(),this._logRunningState()},this._handleBrokerLeave=e=>{delete this._joinedBrokers[e.node.id],this._scaleBack(),this._logRunningState()},this._workerLeaderSelectionPromise=Promise.resolve(),this._options=Object_1.buildOptions(this._options,e),this._logger=new Logger_1.default(this._options.logLevel),this._logger.logBusy("Launching state server..."),this.joinToken=this._getJoinToken(),this.server=new ziron_server_1.Server({port:this._options.port,pingInterval:1e3,path:this._options.path}),this._initServer()}listen(){return __awaiter(this,void 0,void 0,(function*(){this._listenCalled||(this._listenCalled=!0,yield this.server.listen(),this._logger.logActive(`State server launched successfully on port: ${this._options.port}.`),this._logRunningState())}))}_logRunningState(){this._logger.logRunningState(Object.values(this._joinedWorkers),Object.values(this._joinedBrokers),this.joinToken)}_getJoinToken(){const e=ip.address(),t=""===this._options.path||"/"===this._options.path?"":this._options.path.startsWith("/")?this._options.path:"/"+this._options.path;return`${this._options.secret?this._options.secret+"@":""}ws://${isIp.v6(e)?`[${e}]`:e}:${this._options.port}${t}`}_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._options.secret)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.socketMiddleware=e=>{const t=e.handshakeAttachment.node;if("object"!=typeof t||0!==t.type&&1!==t.type||"string"!=typeof t.id||"number"!=typeof t.port||"string"!=typeof t.path)throw new ziron_server_1.Block(4005,"Invalid attachment structure");{const r="string"==typeof t.ip&&isIp(t.ip)?t.ip:e.remoteAddress;if(!r)throw new ziron_server_1.Block(4012,"Could not detect node IP address");if(""!==t.path&&!t.path.startsWith("/"))throw new ziron_server_1.Block(4005,"Invalid node path");e.node={id:t.id,type:t.type,ip:r,port:t.port,path:t.path,uri:`ws://${isIp.v6(r)?`[${r}]`:r}:${t.port}${t.path}`,leader:!1}}},this.server.connectionHandler=e=>{const t=e.node.type;e.on("disconnect",0===t?()=>this._handleWorkerLeave(e):()=>this._handleBrokerLeave(e)),ziron_server_1.applyStandaloneProcedures(e,this.procedures),ziron_server_1.applyStandaloneReceivers(e,this.receivers),e.procedures["#leave"]=0===t?(t,r)=>{this._handleWorkerLeave(e),r()}:(t,r)=>{this._handleBrokerLeave(e),r()},e.procedures["#join"]=0===t?(...t)=>this._handleWorkerJoin(e,...t):(...t)=>this._handleBrokerJoin(e,...t)}}_createClusterSession(e){this._clusterSession={id:uniqId(),shared:e}}_resetClusterSession(){this._clusterSession=null}static _getJoinedState(e){return{time:Date.now(),uris:Object.values(e).map(e=>e.node.uri)}}getJoinedBrokersState(){return StateServer._getJoinedState(this._joinedBrokers)}getJoinedWorkersState(){return StateServer._getJoinedState(this._joinedWorkers)}_getRandomWorker(){return Crypto_1.getRandomArrayItem(Object.values(this._joinedWorkers))}_selectWorkerLeader(){this._workerLeaderSelectionPromise=this._workerLeaderSelectionPromise.then(()=>this._selectWorkerLeaderProcess())}_selectWorkerLeaderProcess(){return __awaiter(this,void 0,void 0,(function*(){let e;if(null==this._workerLeader&&void 0!==(e=this._getRandomWorker())){try{yield e.invoke("addLeadership")}catch(e){return yield this._selectWorkerLeaderProcess()}e.node.leader=!0,this._workerLeader=e,this._logRunningState()}}))}_scaleOut(){this._setScaleTimeout(()=>this._updateWorkersBrokerState())}_scaleBack(){this._setScaleTimeout(()=>this._updateWorkersBrokerState())}_setScaleTimeout(e){null!=this._scaleTimeout&&clearTimeout(this._scaleTimeout),this._scaleTimeout=setTimeout(e,this._options.scaleDelay)}_updateWorkersBrokerState(){this.server.transmitToGroup("JoinedWorkers","updateBrokers",this.getJoinedBrokersState())}_isNodeIdInUse(e){return this._joinedWorkers.hasOwnProperty(e)||this._joinedBrokers.hasOwnProperty(e)||e===this.server.id}terminate(){this._workerLeader=null,this._joinedWorkers={},this._joinedBrokers={},this.server.terminate()}}exports.StateServer=StateServer;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ziron-state",
3
- "version": "6.0.0",
3
+ "version": "6.2.0",
4
4
  "description": "Ziron state",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -18,7 +18,7 @@
18
18
  "email": "lucacode1@gmail.com"
19
19
  },
20
20
  "dependencies": {
21
- "ziron-server": "6.0.0",
21
+ "ziron-server": "6.2.0",
22
22
  "log-update": "^4.0.0",
23
23
  "table": "^6.7.5",
24
24
  "ip": "^1.1.5",