Add status events for create/delete instance

Notify plugins of status changes when instances are created and deleted.
This commit is contained in:
Hornwitser committed 2021-05-12 20:42:52 +02:00
1 parent 67219ede6b
commit f6ab825692
3 files changed
+30 -16

No files matched your search

+13 -5
View File
@@ -252,15 +252,18 @@ class BaseMasterPlugin {
/**
* Called when the status of an instance changes
*
* Invoked when the master server has received notice from a slave that
* the running status of an instance has changed. The possible statuses
* that can be notified about are:
* - `stopped`: Instance is no longer running.
* Invoked when the master server has changed the status of an instance
* or received notice from a slave that the status of an instance has
* changed. The possible statuses that can be notified about are:
* - `unassigned:`: Instance is no longer asssigned to a slave.
* - `stopped`: Instance is no longer running or was just assigned to a
* slave.
* - `starting`: Instance is in the process of starting up.
* - `running`: Instance startup completed and is now running.
* - `creating_save`: Instance is in the process of creating a save.
* - `exporting_data`: Instance is in the process of exporting item
* icons and locale data.
* - `deleted`: Instance was deleted.
*
* On master startup all known instances gets the status `unknown` if
* they are assigned to a slave, when the slave then connects to the
@@ -268,12 +271,17 @@ class BaseMasterPlugin {
* is invoked for all those instances. You can detect this situation by
* checking if prev equals `unknown`.
*
* When instances are created on the master they will notify of a status
* change with prev set to null. While the status of new instances is
* in most cases `unassigned` it's possible for the created instance to
* start with any state in some slave connection corner cases.
*
* Note that it's possible for status change notification to get lost in
* the case of network outages if reconnect fails to re-establish the
* session between the master server and the slave.
*
* @param {Object} instance - the instance that changed.
* @param {string} prev - the previous status of the instance.
* @param {?string} prev - the previous status of the instance.
*/
async onInstanceStatusChanged(instance, prev) { }
+8 -1
View File
@@ -8,6 +8,7 @@ const libErrors = require("@clusterio/lib/errors");
const libLink = require("@clusterio/lib/link");
const { logger } = require("@clusterio/lib/logging");
const libLoggingUtils = require("@clusterio/lib/logging_utils");
const libPlugin = require("@clusterio/lib/plugin");
const libPrometheus = require("@clusterio/lib/prometheus");
const libUsers = require("@clusterio/lib/users");
@@ -170,7 +171,9 @@ class ControlConnection extends BaseConnection {
};
instanceConfig.set("factorio.settings", settings);
this._master.instances.set(instanceId, { config: instanceConfig, status: "unassigned" });
let instance = { config: instanceConfig, status: "unassigned" };
this._master.instances.set(instanceId, instance);
await libPlugin.invokeHook(this._master.plugins, "onInstanceStatusChanged", instance, null);
}
async deleteInstanceRequestHandler(message, request) {
@@ -183,6 +186,10 @@ class ControlConnection extends BaseConnection {
await this.forwardRequestToInstance(message, request);
}
this._master.instances.delete(message.data.instance_id);
let prev = instance.status;
instance.status = "deleted";
await libPlugin.invokeHook(this._master.plugins, "onInstanceStatusChanged", instance, prev);
}
async getInstanceConfigRequestHandler(message) {
+9 -10
View File
@@ -71,9 +71,9 @@ class SlaveConnection extends BaseConnection {
}
// Assign instances the slave has but master does not
for (let instance of message.data.instances) {
for (let instanceData of message.data.instances) {
let instanceConfig = new libConfig.InstanceConfig("master");
await instanceConfig.load(instance.serialized_config, "slave");
await instanceConfig.load(instanceData.serialized_config, "slave");
let masterInstance = this._master.instances.get(instanceConfig.get("instance.id"));
if (masterInstance) {
@@ -86,24 +86,23 @@ class SlaveConnection extends BaseConnection {
}
// Already have this instance, update state instead
if (masterInstance.status !== instance.status) {
if (masterInstance.status !== instanceData.status) {
let prev = masterInstance.status;
masterInstance.status = instance.status;
logger.verbose(`Instance ${instanceConfig.get("instance.name")} State: ${instance.status}`);
await libPlugin.invokeHook(this._master.plugins, "onInstanceStatusChanged", instance, prev);
masterInstance.status = instanceData.status;
logger.verbose(`Instance ${instanceConfig.get("instance.name")} State: ${instanceData.status}`);
await libPlugin.invokeHook(this._master.plugins, "onInstanceStatusChanged", masterInstance, prev);
}
continue;
}
instanceConfig.set("instance.assigned_slave", this._id);
this._master.instances.set(instanceConfig.get("instance.id"), {
config: instanceConfig,
status: instance.status,
});
let newInstance = { config: instanceConfig, status: instanceData.status };
this._master.instances.set(instanceConfig.get("instance.id"), newInstance);
await libLink.messages.assignInstance.send(this, {
instance_id: instanceConfig.get("instance.id"),
serialized_config: instanceConfig.serialize("slave"),
});
await libPlugin.invokeHook(this._master.plugins, "onInstanceStatusChanged", newInstance, null);
}
// Push lists to make sure they are in sync.