mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-14 07:24:52 +09:00
Separate connection related data from host data
Split out host specific data from RegisterHostData that is not related to the establishment of a connection to the controller into it's own HostInfoUpdate event. This allows this data to be updated when the config values they are taken from are changed.
This commit is contained in:
1 parent
790f880e98
commit
688ddc529b
8 files changed
+94
-42
No files matched your search
@@ -108,7 +108,6 @@ Host handshake for establishing a new connection session.
|
||||
|
||||
- `token: string` - Authentication token.
|
||||
- `version: string` - The protocol version of the host, e.g. "2.0.0".
|
||||
- `name: string` - Name of the host.
|
||||
- `id: integer` - ID of the host.
|
||||
- `plugins: Object<string, string>` -
|
||||
Object mapping plugin names to plugin version for plugins that are available on the host.
|
||||
@@ -242,7 +241,6 @@ Host registering a new connection session.
|
||||
"data": {
|
||||
"token": "xyzabc123",
|
||||
"version": "2.0.0",
|
||||
"name": "Foo",
|
||||
"id": 123
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,9 +16,7 @@ import HostInfo from "./HostInfo";
|
||||
* @alias module:controller/src/HostConnection
|
||||
*/
|
||||
export default class HostConnection extends BaseConnection {
|
||||
private _id: number;
|
||||
private _name: string;
|
||||
private _version: string;
|
||||
private info: HostInfo;
|
||||
plugins: Map<string, string>;
|
||||
|
||||
constructor(
|
||||
@@ -28,26 +26,24 @@ export default class HostConnection extends BaseConnection {
|
||||
) {
|
||||
super(connector, controller);
|
||||
|
||||
this._id = registerData.id;
|
||||
this._name = registerData.name;
|
||||
this._version = registerData.version;
|
||||
this.plugins = new Map(Object.entries(registerData.plugins));
|
||||
this._checkPluginVersions();
|
||||
|
||||
const previousHostInfo = this._controller.hosts.get(this._id);
|
||||
const currentHostInfo = new HostInfo(
|
||||
this._id,
|
||||
this._name,
|
||||
this._version,
|
||||
const previousHostInfo = this._controller.hosts.get(registerData.id);
|
||||
this.info = new HostInfo(
|
||||
registerData.id,
|
||||
previousHostInfo?.name ?? "",
|
||||
registerData.version,
|
||||
this.plugins,
|
||||
true,
|
||||
registerData.publicAddress ?? "",
|
||||
previousHostInfo?.publicAddress,
|
||||
previousHostInfo?.tokenValidAfter,
|
||||
Date.now(),
|
||||
0,
|
||||
false,
|
||||
);
|
||||
this._controller.hosts.set(this._id, currentHostInfo);
|
||||
this._controller.hostsUpdated([currentHostInfo]);
|
||||
this._controller.hosts.set(this.id, this.info);
|
||||
this._controller.hostsUpdated([this.info]);
|
||||
|
||||
this._checkPluginVersions();
|
||||
|
||||
for (let event of ["connect", "drop", "resume", "close"] as const) {
|
||||
// eslint-disable-next-line no-loop-func
|
||||
@@ -62,7 +58,7 @@ export default class HostConnection extends BaseConnection {
|
||||
// Update status to unknown for instances on this host.
|
||||
const instances: InstanceInfo[] = [];
|
||||
for (let instance of this._controller.instances.values()) {
|
||||
if (instance.config.get("instance.assigned_host") !== this._id) {
|
||||
if (instance.config.get("instance.assigned_host") !== this.id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -73,10 +69,11 @@ export default class HostConnection extends BaseConnection {
|
||||
}
|
||||
this._controller.instanceDetailsUpdated(instances);
|
||||
|
||||
currentHostInfo.connected = false;
|
||||
this._controller.hostsUpdated([currentHostInfo]);
|
||||
this.info.connected = false;
|
||||
this._controller.hostsUpdated([this.info]);
|
||||
});
|
||||
|
||||
this.handle(lib.HostInfoUpdateEvent, this.handleHostInfoUpdateEvent.bind(this));
|
||||
this.handle(lib.InstanceStatusChangedEvent, this.handleInstanceStatusChangedEvent.bind(this));
|
||||
this.handle(lib.InstancesUpdateRequest, this.handleInstancesUpdateRequest.bind(this));
|
||||
this.handle(lib.InstanceSaveDetailsUpdatesEvent, this.handleInstanceSaveDetailsUpdatesEvent.bind(this));
|
||||
@@ -101,7 +98,7 @@ export default class HostConnection extends BaseConnection {
|
||||
|
||||
case lib.Address.instance:
|
||||
let instance = this._controller.instances.get(message.src.id);
|
||||
if (!instance || instance.config.get("instance.assigned_host") !== this._id) {
|
||||
if (!instance || instance.config.get("instance.assigned_host") !== this.id) {
|
||||
throw new lib.InvalidMessage(
|
||||
`Received message with invalid src ${message.src} from ${origin}`
|
||||
);
|
||||
@@ -118,21 +115,24 @@ export default class HostConnection extends BaseConnection {
|
||||
for (let [name, version] of this.plugins) {
|
||||
let info = pluginInfos.get(name);
|
||||
if (!info) {
|
||||
logger.warn(`Host ${this._name} has plugin ${name} ${version} which the controller does not have`);
|
||||
logger.warn(
|
||||
`Host ${this.info.name} (${this.id}) has plugin ${name} ${version} which the ` +
|
||||
"controller does not have",
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (info.version !== version) {
|
||||
logger.warn(
|
||||
`Host ${this._name} has plugin ${name} ${version} which does not match the version of this ` +
|
||||
`plugin on the controller (${info.version})`
|
||||
`Host ${this.info.name} (${this.id}) has plugin ${name} ${version} which does not match ` +
|
||||
`the version of this plugin on the controller (${info.version})`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
for (let [name, info] of pluginInfos) {
|
||||
if (!this.plugins.has(name)) {
|
||||
logger.warn(`Host ${this._name} is missing plugin ${name} ${info.version}`);
|
||||
logger.warn(`Host ${this.info.name} (${this.id}) is missing plugin ${name} ${info.version}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -148,7 +148,13 @@ export default class HostConnection extends BaseConnection {
|
||||
* @returns {number} host ID.
|
||||
*/
|
||||
get id() {
|
||||
return this._id;
|
||||
return this.info.id;
|
||||
}
|
||||
|
||||
async handleHostInfoUpdateEvent(event: lib.HostInfoUpdateEvent) {
|
||||
this.info.name = event.update.name;
|
||||
this.info.publicAddress = event.update.publicAddress;
|
||||
this._controller.hostsUpdated([this.info]);
|
||||
}
|
||||
|
||||
async handleInstanceStatusChangedEvent(request: lib.InstanceStatusChangedEvent) {
|
||||
@@ -158,7 +164,7 @@ export default class HostConnection extends BaseConnection {
|
||||
// or is not assigned to the host it originated from if it was
|
||||
// reassigned or deleted while the connection to the host it was
|
||||
// originally on was down at the time.
|
||||
if (!instance || instance.config.get("instance.assigned_host") !== this._id) {
|
||||
if (!instance || instance.config.get("instance.assigned_host") !== this.id) {
|
||||
logger.warn(`Got bogus update for instance id ${request.instanceId}`);
|
||||
return;
|
||||
}
|
||||
@@ -184,7 +190,7 @@ export default class HostConnection extends BaseConnection {
|
||||
async handleInstancesUpdateRequest(request: lib.InstancesUpdateRequest) {
|
||||
// Push updated instance configs
|
||||
for (let instance of this._controller.instances.values()) {
|
||||
if (instance.config.get("instance.assigned_host") === this._id) {
|
||||
if (instance.config.get("instance.assigned_host") === this.id) {
|
||||
await this.send(
|
||||
new lib.InstanceAssignInternalRequest(instance.id, instance.config.toRemote("host"))
|
||||
);
|
||||
@@ -200,7 +206,7 @@ export default class HostConnection extends BaseConnection {
|
||||
let controllerInstance = this._controller.instances.get(instanceConfig.get("instance.id"));
|
||||
if (controllerInstance) {
|
||||
// Check if this instance is assigned somewhere else.
|
||||
if (controllerInstance.config.get("instance.assigned_host") !== this._id) {
|
||||
if (controllerInstance.config.get("instance.assigned_host") !== this.id) {
|
||||
await this.send(
|
||||
new lib.InstanceUnassignInternalRequest(instanceConfig.get("instance.id"))
|
||||
);
|
||||
@@ -222,7 +228,7 @@ export default class HostConnection extends BaseConnection {
|
||||
continue;
|
||||
}
|
||||
|
||||
instanceConfig.set("instance.assigned_host", this._id);
|
||||
instanceConfig.set("instance.assigned_host", this.id);
|
||||
let newInstance = new InstanceInfo(
|
||||
instanceConfig,
|
||||
instanceData.status,
|
||||
@@ -298,8 +304,8 @@ export default class HostConnection extends BaseConnection {
|
||||
async handleLogMessageEvent(event: lib.LogMessageEvent) {
|
||||
this._controller.clusterLogger.log({
|
||||
...event.info,
|
||||
host_id: this._id,
|
||||
host_name: this._name,
|
||||
host_id: this.id,
|
||||
host_name: this.info.name,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -261,11 +261,11 @@ ${err.stack}`
|
||||
}
|
||||
|
||||
logger.info(
|
||||
`WsServer | registered host ${data.name} (${data.id}) using version ${data.version}`
|
||||
`WsServer | registered host ${data.id} using version ${data.version}`
|
||||
);
|
||||
if (data.version !== packageVersion) {
|
||||
logger.warn(
|
||||
`Host ${data.name} (${data.id}) connected using version ${data.version} which does not match the ` +
|
||||
`Host ${data.id} connected using version ${data.version} which does not match the ` +
|
||||
`version of the controller is currently running (${packageVersion}). It may not work as expected.`
|
||||
);
|
||||
}
|
||||
|
||||
@@ -52,9 +52,7 @@ export class HostConnector extends lib.WebSocketClientConnector {
|
||||
new lib.RegisterHostData(
|
||||
this.hostConfig.get("host.controller_token"),
|
||||
version,
|
||||
this.hostConfig.get("host.name"),
|
||||
this.hostConfig.get("host.id"),
|
||||
this.hostConfig.get("host.public_address"),
|
||||
plugins,
|
||||
)
|
||||
)
|
||||
|
||||
@@ -288,6 +288,9 @@ export default class Host extends lib.Link {
|
||||
this.config = hostConfig;
|
||||
|
||||
this.config.on("fieldChanged", (name, curr, prev) => {
|
||||
if (name === "host.name" || name === "host.public_address") {
|
||||
this.sendHostUpdate();
|
||||
}
|
||||
lib.invokeHook(this.plugins, "onHostConfigFieldChanged", name, curr, prev);
|
||||
});
|
||||
|
||||
@@ -301,6 +304,7 @@ export default class Host extends lib.Link {
|
||||
return;
|
||||
}
|
||||
|
||||
this.sendHostUpdate();
|
||||
this.updateInstances().catch((err) => {
|
||||
if (err instanceof lib.SessionLost) {
|
||||
return undefined;
|
||||
@@ -992,6 +996,17 @@ export default class Host extends lib.Link {
|
||||
await fs.remove(instanceInfo.path);
|
||||
}
|
||||
|
||||
sendHostUpdate() {
|
||||
this.send(
|
||||
new lib.HostInfoUpdateEvent(
|
||||
new lib.HostInfoUpdate(
|
||||
this.config.get("host.name"),
|
||||
this.config.get("host.public_address"),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Discover available instances
|
||||
*
|
||||
|
||||
@@ -212,23 +212,19 @@ export class RegisterHostData {
|
||||
constructor(
|
||||
public token: string,
|
||||
public version: string,
|
||||
public name: string,
|
||||
public id: number,
|
||||
public publicAddress: string | undefined,
|
||||
public plugins: Record<string, string>,
|
||||
) { }
|
||||
|
||||
static jsonSchema = Type.Object({
|
||||
"token": Type.String(),
|
||||
"version": Type.String(),
|
||||
"name": Type.String(),
|
||||
"id": Type.Integer(),
|
||||
"publicAddress": Type.Optional(Type.String()),
|
||||
"plugins": Type.Record(Type.String(), Type.String()),
|
||||
});
|
||||
|
||||
static fromJSON(json: Static<typeof this.jsonSchema>) {
|
||||
return new this(json.token, json.version, json.name, json.id, json.publicAddress, json.plugins);
|
||||
return new this(json.token, json.version, json.id, json.plugins);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -105,6 +105,44 @@ export class HostListRequest {
|
||||
static Response = jsonArray(HostDetails);
|
||||
}
|
||||
|
||||
export class HostInfoUpdate {
|
||||
constructor(
|
||||
public name: string,
|
||||
public publicAddress: string,
|
||||
) { }
|
||||
|
||||
static jsonSchema = Type.Object({
|
||||
"name": Type.String(),
|
||||
"publicAddress": Type.String(),
|
||||
});
|
||||
|
||||
static fromJSON(json: Static<typeof this.jsonSchema>) {
|
||||
return new this(
|
||||
json.name,
|
||||
json.publicAddress,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export class HostInfoUpdateEvent {
|
||||
declare ["constructor"]: typeof HostInfoUpdateEvent;
|
||||
static type = "event" as const;
|
||||
static src = "host" as const;
|
||||
static dst = "controller" as const;
|
||||
|
||||
constructor(
|
||||
public update: HostInfoUpdate,
|
||||
) { }
|
||||
|
||||
static jsonSchema = Type.Object({
|
||||
"update": HostInfoUpdate.jsonSchema,
|
||||
});
|
||||
|
||||
static fromJSON(json: Static<typeof this.jsonSchema>) {
|
||||
return new this(HostInfoUpdate.fromJSON(json.update));
|
||||
}
|
||||
}
|
||||
|
||||
export class HostUpdatesEvent {
|
||||
declare ["constructor"]: typeof HostUpdatesEvent;
|
||||
static type = "event" as const;
|
||||
|
||||
@@ -36,6 +36,7 @@ export const dataClasses: (RequestClass<unknown, unknown> | EventClass<unknown>)
|
||||
host.HostConfigSetFieldRequest,
|
||||
host.HostConfigSetPropRequest,
|
||||
host.HostListRequest,
|
||||
host.HostInfoUpdateEvent,
|
||||
host.HostUpdatesEvent,
|
||||
host.HostMetricsRequest,
|
||||
host.ControllerConnectionEvent,
|
||||
|
||||
Reference in new issue
Block a user