Send inventory on interval instead of event to ensure time gets updated (#790)

This means inventory updates in low-volume clusters might be delayed up to 1 second more, but ensures we always have the unix time signal available, even in clusters that don't have anything in the inventory yet. Resolves #610
This commit is contained in:
Daniel authored and GitHub committed 2025-08-10 22:25:32 +01:00
1 parent 4221b96431
commit c0ec9a3890
1 file changed
+26 -12
+26 -12
View File
@@ -14,6 +14,8 @@ type IpcItems = [name: string, count: number, quality: string][];
export class InstancePlugin extends BaseInstancePlugin {
pendingTasks!: Set<any>;
pingId?: ReturnType<typeof setTimeout>;
timeUpdateId?: ReturnType<typeof setInterval>;
cachedInventoryItems: Item[] = [];
unexpectedError(err: Error) {
this.logger.error(`Unexpected error:\n${err.stack}`);
@@ -54,18 +56,37 @@ export class InstancePlugin extends BaseInstancePlugin {
}, 5000);
let items = await this.instance.sendTo("controller", new GetStorageRequest());
// TODO Diff with dump of invdata produce minimal command to sync
let itemsJson = lib.escapeString(JSON.stringify(items));
await this.sendRcon(`/sc __subspace_storage__ UpdateInvData("${itemsJson}", true)`, true);
// Cache items for periodic time updates
this.cachedInventoryItems = items;
// Ensure a payload with updated time is sent every second
this.timeUpdateId = setInterval(() => {
if (this.instance.status !== "running") {
return;
}
const payloadItems = [
...this.cachedInventoryItems,
new Item("signal-unixtime", Math.floor(Date.now() / 1000), "normal"),
];
const payloadJson = lib.escapeString(JSON.stringify(payloadItems));
const task = this.sendRcon(`/sc __subspace_storage__ UpdateInvData("${payloadJson}")`, true)
.catch(err => this.unexpectedError(err));
this.pendingTasks.add(task);
task.finally(() => { this.pendingTasks.delete(task); });
}, 1000);
}
async onStop() {
clearInterval(this.pingId);
clearInterval(this.timeUpdateId);
await Promise.all(this.pendingTasks);
}
onExit() {
clearInterval(this.pingId);
clearInterval(this.timeUpdateId);
}
// provide items --------------------------------------------------------------
@@ -114,14 +135,7 @@ export class InstancePlugin extends BaseInstancePlugin {
if (this.instance.status !== "running") {
return;
}
let items = event.items;
// XXX this should be moved to instance/clusterio api
items.push(new Item("signal-unixtime", Math.floor(Date.now()/1000), "normal"));
let itemsJson = lib.escapeString(JSON.stringify(items));
let task = this.sendRcon(`/sc __subspace_storage__ UpdateInvData("${itemsJson}")`, true);
this.pendingTasks.add(task);
await task.finally(() => { this.pendingTasks.delete(task); });
// Cache latest inventory from controller
this.cachedInventoryItems = event.items;
}
}