From 33efb32aa972148af63c73f6f805002f2048134f Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Fri, 10 Sep 2021 21:56:24 +0200 Subject: [PATCH] Add connected property to Slave and BaseConnection Provide a convenience method for checking if the Master-Slave link is fully online via a .connected property. This is true if the link has been establised, is not in the dropped state, and not in the process of disconnecting. --- docs/writing-plugins.md | 10 +++++----- packages/master/src/BaseConnection.js | 11 +++++++++++ packages/slave/slave.js | 11 ++++++++++- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/docs/writing-plugins.md b/docs/writing-plugins.md index 2165b48e..b1871b63 100644 --- a/docs/writing-plugins.md +++ b/docs/writing-plugins.md @@ -502,11 +502,11 @@ This is signaled to `MasterPlugin` classes via the `onPrepareSlaveDisconnect` ho After the prepare disconnect the connection will be closed, which will result in pending requests and events being dropped. Plugins must respond to the prepare disconnect by stopping any processess it does that send events or requests over the link in question. -This can be accomplished either through listening for the prepare disconnect hook, or by checking the `connected` or `closing` property of the connector for the master/slave connection. -For example the sending of an event from an `InstancePlugin` class can be stopped while the connection is closing by using the following code: +This can be accomplished either through listening for the prepare disconnect hook, or by checking the `connected` property of the `SlaveConnection` class and `Slave` class on the master and slave respectively. +For example the sending of an event from an `InstancePlugin` class can be stopped while the connection is not connected, not in the dropped state, and not in the process of discunnecting by using the following code: ```js -if (!this.slave.connector.closing) { +if (this.slave.connected) { this.info.messages.frobnicate.send(this.instance, { foo: "bar" }); } ``` @@ -517,8 +517,8 @@ The re-establishement of the connection is notified to plugins via the `connect The second connection event which is of lesser importance to respond to is the `drop` connection event served through `onMasterConnectionEvent` for `InstancePlugin` classes and through `onSlaveConnectionEvent` for `MasterPlugin` classes. This is raised when the connection between the master and slave in question is lost, most likely due to networking issues. When in the dropped state the slave will keep trying to reconnect to the master server in order to re-establish it, and if successful no events or requests will be lost. -However while in the dropped state any requests and events sent gets queued up in memory until the connection is re-established. -This means that if your plugin sends a lot of events or requests, they can end up being queued up in a buffer for a long time and sent out all at once. +However while in the dropped state any requests and events sent gets queued up in memory until the connection is either re-established or the session times out. +This means that if your plugin sends a lot of events or requests, they can end up being queued up in a buffer and sent out all at once the connection is re-estabished. To avoid this you should be throtteling and/or stopping your requests/events after `drop` has been raised, and continue back as normal when `resume` is raised. diff --git a/packages/master/src/BaseConnection.js b/packages/master/src/BaseConnection.js index 232b1942..44c086e6 100644 --- a/packages/master/src/BaseConnection.js +++ b/packages/master/src/BaseConnection.js @@ -16,6 +16,7 @@ class BaseConnection extends libLink.Link { /** @member {module:master/src/WsServerConnector} module:master/src/BaseConnection#connector */ super("master", target, connector); this._master = master; + this._disconnecting = false; libLink.attachAllMessages(this); for (let masterPlugin of this._master.plugins.values()) { libPlugin.attachPluginMessages(this, masterPlugin); @@ -57,6 +58,7 @@ class BaseConnection extends libLink.Link { async prepareDisconnectRequestHandler(message, request) { await libPlugin.invokeHook(this._master.plugins, "onPrepareSlaveDisconnect", this); + this._disconnecting = true; this.connector.setClosing(); return await super.prepareDisconnectRequestHandler(message, request); } @@ -72,6 +74,15 @@ class BaseConnection extends libLink.Link { await this.connector.close(code, reason); } + + /** + * True if the link is connected, not in the dropped state and not in + * the process of disconnecting. + * @type {boolean} + */ + get connected() { + return !this._disconnecting && this.connector.connected; + } } module.exports = BaseConnection; diff --git a/packages/slave/slave.js b/packages/slave/slave.js index ed9e9ac8..de89a7ed 100755 --- a/packages/slave/slave.js +++ b/packages/slave/slave.js @@ -1582,10 +1582,10 @@ class Slave extends libLink.Link { } async prepareDisconnectRequestHandler(message, request) { - this._disconnecting = true; for (let instanceConnection of this.instanceConnections.values()) { await libLink.messages.prepareMasterDisconnect.send(instanceConnection); } + this._disconnecting = true; this.connector.setClosing(); return await super.prepareDisconnectRequestHandler(message, request); } @@ -1628,6 +1628,15 @@ ${err.stack}` process.exit(1); } } + + /** + * True if the connection to the master is connected, not in the dropped + * state,and not in the process of disconnecting. + * @type {boolean} + */ + get connected() { + return !this._disconnecting && this.connector.connected; + } } /**