Add isDeleted and updatedAt to subscribable types

Prepare for subscriptinos being able to be cached and resumed by adding
updatedAt and isDeleted fields to the subscribable types.
This commit is contained in:
Hornwitser committed 2023-12-08 18:22:34 +01:00
1 parent 58914042cc
commit f12a9926eb
10 files changed
+65 -4

No files matched your search

+5 -1
View File
@@ -735,7 +735,7 @@ export default class Controller {
// Assign to target
instance.config.set("instance.assigned_host", hostId);
this.instancesDirty = true;
// "fieldChanged" event handler will set this.instancesDirty
if (hostId !== undefined && newHostConnection) {
await newHostConnection.send(
new lib.InstanceAssignInternalRequest(instanceId, instance.config.serialize("host"))
@@ -819,6 +819,7 @@ export default class Controller {
assigned_host,
game_port,
instance.status,
Date.now(),
)
));
}
@@ -828,17 +829,20 @@ export default class Controller {
}
modPackUpdated(modPack: lib.ModPack) {
modPack.updatedAt = Date.now();
this.modPacksDirty = true;
this.subscriptions.broadcast(new lib.ModPackUpdateEvent(modPack));
lib.invokeHook(this.plugins, "onModPackUpdated", modPack);
}
modUpdated(mod: lib.ModInfo) {
// ModStore sets updatedAt for mods
this.subscriptions.broadcast(new lib.ModUpdateEvent(mod));
lib.invokeHook(this.plugins, "onModUpdated", mod);
}
userUpdated(user: ControllerUser) {
user.updatedAt = Date.now();
this.userManager.dirty = true;
this.subscriptions.broadcast(new lib.UserUpdateEvent(user));
}
@@ -35,6 +35,7 @@ export default class ControllerUser extends User implements IControllerUser {
json.is_banned,
json.is_whitelisted,
json.ban_reason,
json.updated_at,
json.is_deleted,
playerStats,
instanceStats,
+1
View File
@@ -66,6 +66,7 @@ export default class ModStore extends TypedEventEmitter<keyof ModStoreEvents, Mo
await fs.unlink(path.join(this.modsDirectory, file));
this.files.delete(file);
modInfo.isDeleted = true;
modInfo.updatedAt = Date.now();
this.emit("change", modInfo);
}
+9 -1
View File
@@ -113,6 +113,9 @@ export default class ModInfo {
*/
sha1?: string;
/** Millisecond Unix timestamp this entry was last updated at */
updatedAt = 0;
/**
* True if this mod has been deleted
*/
@@ -137,6 +140,7 @@ export default class ModInfo {
...this.infoJsonSchema.properties,
"size": Type.Optional(Type.Integer()),
"sha1": Type.Optional(Type.String()),
"updated_at": Type.Optional(Type.Number()),
"is_deleted": Type.Optional(Type.Boolean()),
});
@@ -159,6 +163,7 @@ export default class ModInfo {
// Additional data
if (json.size) { modInfo.size = json.size; }
if (json.sha1) { modInfo.sha1 = json.sha1; }
if (json.updated_at) { modInfo.updatedAt = json.updated_at; }
if (json.is_deleted) { modInfo.isDeleted = json.is_deleted; }
return modInfo;
@@ -180,6 +185,7 @@ export default class ModInfo {
}
if (this.size) { json.size = this.size; }
if (this.sha1) { json.sha1 = this.sha1; }
if (this.updatedAt) { json.updated_at = this.updatedAt; }
if (this.isDeleted) { json.is_deleted = this.isDeleted; }
return json;
}
@@ -209,11 +215,13 @@ export default class ModInfo {
throw new Error(`Mod's version (${modInfo.version}) is invalid`);
}
const stat = await fs.stat(modPath);
return this.fromJSON({
...modInfo,
size: (await fs.stat(modPath)).size,
size: stat.size,
sha1: await libHash.hashFile(modPath),
updated_at: stat.mtimeMs,
is_deleted: false,
});
}
+9
View File
@@ -101,6 +101,9 @@ export default class ModPack {
*/
exportManifest?: ExportManifest;
/** Millisecond Unix timestamp this entry was last updated at */
updatedAt = 0;
/**
* True if this mod pack has been deleted from the list of mod packs.
*/
@@ -115,6 +118,7 @@ export default class ModPack {
clone.mods = this.mods;
clone.settings = this.settings;
clone.exportManifest = this.exportManifest;
clone.updatedAt = this.updatedAt;
clone.isDeleted = this.isDeleted;
return clone;
}
@@ -131,6 +135,7 @@ export default class ModPack {
"runtime-per-user": ModSettingsJsonSchema,
}),
"export_manifest": Type.Optional(ExportManifest.jsonSchema),
"updated_at": Type.Optional(Type.Number()),
"is_deleted": Type.Optional(Type.Boolean()),
});
@@ -156,6 +161,7 @@ export default class ModPack {
};
}
if (json.export_manifest) { modPack.exportManifest = ExportManifest.fromJSON(json.export_manifest); }
if (json.updated_at) { modPack.updatedAt = json.updated_at; }
if (json.is_deleted) { modPack.isDeleted = json.is_deleted; }
if (!modPack.mods.has("base")) {
@@ -179,6 +185,7 @@ export default class ModPack {
},
};
if (this.exportManifest) { json.export_manifest = this.exportManifest; }
if (this.updatedAt) { json.updated_at = this.updatedAt; }
if (this.isDeleted) { json.is_deleted = this.isDeleted; }
return json;
}
@@ -187,6 +194,8 @@ export default class ModPack {
const json = this.toJSON();
delete json.id;
delete json.export_manifest;
delete json.updated_at;
delete json.is_deleted;
// eslint-disable-next-line node/no-sync
let buf = zlib.deflateSync(JSON.stringify(json));
+8
View File
@@ -23,6 +23,8 @@ export default class User {
public isWhitelisted = false,
/** Reason for being banned. Ignored if isBanned is false. */
public banReason = "",
/** Millisecond Unix timestamp this entry was last updated at */
public updatedAt = 0,
/** True if this user object has been removed from the cluster. */
public isDeleted = false,
/** Combined statistics for the player this user account is tied to. */
@@ -40,6 +42,7 @@ export default class User {
is_banned: Type.Optional(Type.Boolean()),
is_whitelisted: Type.Optional(Type.Boolean()),
ban_reason: Type.Optional(Type.String()),
updated_at: Type.Optional(Type.Number()),
is_deleted: Type.Optional(Type.Boolean()),
instance_stats: Type.Optional(
Type.Array(
@@ -64,6 +67,7 @@ export default class User {
json.is_banned,
json.is_whitelisted,
json.ban_reason,
json.updated_at,
json.is_deleted,
playerStats,
instanceStats,
@@ -99,6 +103,10 @@ export default class User {
json.ban_reason = this.banReason;
}
if (this.updatedAt) {
json.updated_at = this.updatedAt;
}
if (this.isDeleted) {
json.is_deleted = this.isDeleted;
}
+7
View File
@@ -11,6 +11,9 @@ export class HostDetails {
public connected: boolean,
public publicAddress?: string,
public tokenValidAfter?: number,
/** Millisecond Unix timestamp this entry was last updated at */
public updatedAt = 0,
public isDeleted = false,
) { }
static jsonSchema = Type.Object({
@@ -21,6 +24,8 @@ export class HostDetails {
"connected": Type.Boolean(),
"publicAddress": Type.Optional(Type.String()),
"tokenValidAfter": Type.Optional(Type.Number()),
"updatedAt": Type.Optional(Type.Number()),
"isDeleted": Type.Optional(Type.Boolean()),
});
static fromJSON(json: Static<typeof this.jsonSchema>) {
@@ -32,6 +37,8 @@ export class HostDetails {
json.connected,
json.publicAddress,
json.tokenValidAfter,
json.updatedAt,
json.isDeleted,
);
}
}
+22 -2
View File
@@ -18,6 +18,8 @@ export class InstanceDetails {
public assignedHost: number | undefined,
public gamePort: number | undefined,
public status: InstanceStatus,
/** Millisecond Unix timestamp this entry was last updated at */
public updatedAt = 0,
) { }
static jsonSchema = Type.Object({
@@ -29,10 +31,22 @@ export class InstanceDetails {
"unknown", "unassigned", "stopped", "starting", "running", "stopping",
"creating_save", "exporting_data", "deleted",
]),
"updatedAt": Type.Optional(Type.Number()),
});
static fromJSON(json: Static<typeof this.jsonSchema>) {
return new this(json.name, json.id, json.assignedHost, json.gamePort, json.status);
return new this(
json.name,
json.id,
json.assignedHost,
json.gamePort,
json.status,
json.updatedAt,
);
}
get isDeleted() {
return this.status === "deleted";
}
}
@@ -288,15 +302,21 @@ export class InstanceSaveListUpdateEvent {
constructor(
public instanceId: number,
public saves: SaveDetails[],
public updatedAt = Date.now(),
) { }
get isDeleted() {
return false;
}
static jsonSchema = Type.Object({
"instanceId": Type.Integer(),
"saves": Type.Array(SaveDetails.jsonSchema),
"updatedAt": Type.Number(),
});
static fromJSON(json: Static<typeof this.jsonSchema>) {
return new this(json.instanceId, json.saves.map(i => SaveDetails.fromJSON(i)));
return new this(json.instanceId, json.saves.map(i => SaveDetails.fromJSON(i)), json.updatedAt);
}
}
+2
View File
@@ -885,6 +885,7 @@ describe("Integration of Clusterio", function() {
reference.settings["runtime-global"].set("MyInt", { value: 1235 });
reference.settings["runtime-global"].set("MyDouble", { value: 12.25 });
reference.settings["runtime-per-user"].set("MyString", { value: "a-string" });
reference.updatedAt = modPack.updatedAt;
assert.deepEqual(modPack, reference);
});
});
@@ -989,6 +990,7 @@ describe("Integration of Clusterio", function() {
"dependencies:\n" +
`size: ${stat.size}\n` +
`sha1: ${hash}\n` +
`updatedAt: ${stat.mtimeMs}\n` +
"isDeleted: false\n",
);
});
+1
View File
@@ -92,6 +92,7 @@ describe("lib/data/ModInfo", function() {
dependencies: [],
filename: "empty_mod_1.0.0.zip",
size: stat.size,
updated_at: stat.mtimeMs,
sha1: hash,
})
);