Files
server-manager/manager/src/wrapperRegistry.ts
T

253 lines
3.7 KiB
TypeScript

import { getLogger } from "./logger";
import { WrapperStatusMessage } from "server-manager-shared";
import { JsonFileStore } from "./persistence/jsonFileStore";
const logger = getLogger("WrapperRegistry");
export interface WrapperInfo {
id:string;
hostname:string;
commandQueue:string;
cpu:number;
ram:number;
ramFree:number;
online:boolean;
lastHeartbeat:number;
servers: WrapperStatusMessage["servers"];
}
interface WrapperRegistryState {
wrappers: Array<{
id:string;
hostname:string;
commandQueue:string;
cpu:number;
ram:number;
}>;
}
export class WrapperRegistry {
private wrappers =
new Map<string, WrapperInfo>();
private readonly persistence =
new JsonFileStore<WrapperRegistryState>(
"wrapperRegistry-state.json"
);
async init(): Promise<void> {
const state = await this.persistence.load();
if (!state)
return;
for (const wrapperData of state.wrappers) {
this.wrappers.set(
wrapperData.id,
{
id: wrapperData.id,
hostname: wrapperData.hostname,
commandQueue: wrapperData.commandQueue,
cpu: wrapperData.cpu,
ram: wrapperData.ram,
ramFree: wrapperData.ram,
online: false,
lastHeartbeat: 0,
servers: []
}
);
}
}
private toState(): WrapperRegistryState {
return {
wrappers: Array.from(this.wrappers.values()).map(
wrapper => ({
id: wrapper.id,
hostname: wrapper.hostname,
commandQueue: wrapper.commandQueue,
cpu: wrapper.cpu,
ram: wrapper.ram
})
)
};
}
private async saveState(): Promise<void> {
await this.persistence.save(
this.toState()
);
}
add(wrapper:WrapperInfo){
this.wrappers.set(
wrapper.id,
wrapper
);
logger.info(
"Wrapper added:",
wrapper.id
);
void this.saveState();
}
get(id:string){
return this.wrappers.get(id);
}
getAll(){
return Array.from(
this.wrappers.values()
);
}
updateHeartbeat(id:string){
const wrapper =
this.wrappers.get(id);
if(!wrapper)
return;
wrapper.lastHeartbeat =
Date.now();
wrapper.online =
true;
}
update(wrapper:WrapperInfo){
this.wrappers.set(
wrapper.id,
wrapper
);
void this.saveState();
}
checkOffline(timeout:number){
const now =
Date.now();
for(const wrapper of this.wrappers.values()){
if(
wrapper.online &&
now - wrapper.lastHeartbeat > timeout
){
wrapper.online = false;
logger.warn(
"Wrapper offline:",
wrapper.id
);
}
}
}
updateStatus(data: WrapperStatusMessage){
const wrapper =
this.wrappers.get(
data.wrapperId
);
if(!wrapper)
return;
wrapper.ramFree =
data.ramFree;
wrapper.servers =
data.servers;
wrapper.lastHeartbeat =
Date.now();
wrapper.online =
true;
}
}