initial import server-manager
This commit is contained in:
+7
-2
@@ -1,7 +1,12 @@
|
||||
node_modules/
|
||||
dist/
|
||||
build/
|
||||
.env
|
||||
|
||||
*.log
|
||||
|
||||
.vscode/
|
||||
.env
|
||||
|
||||
*-state.json
|
||||
|
||||
.vscode/
|
||||
.idea/
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"usedPorts": [
|
||||
7777,
|
||||
7778
|
||||
],
|
||||
"usedQueryPorts": [
|
||||
27015,
|
||||
27016
|
||||
]
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"servers": [
|
||||
{
|
||||
"id": "srv-ba25028b",
|
||||
"name": "[EU] druecktieR | Crimson",
|
||||
"wrapperId": "wrp-8adcbbf2",
|
||||
"port": 7777,
|
||||
"queryPort": 27015,
|
||||
"created": 1784578015578
|
||||
},
|
||||
{
|
||||
"id": "srv-d70d5c3a",
|
||||
"name": "[EU] druecktieR | Azure",
|
||||
"wrapperId": "wrp-8adcbbf2",
|
||||
"port": 7778,
|
||||
"queryPort": 27016,
|
||||
"created": 1784653753332
|
||||
}
|
||||
]
|
||||
}
|
||||
+15
-8
@@ -1,14 +1,21 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.QUERY_PORT_START = exports.GAME_PORT_START = exports.DEFAULT_DESIRED_SERVERS = exports.LIFECYCLE_CRASH_TIMEOUT = exports.LIFECYCLE_SCALE_COOLDOWN = exports.LIFECYCLE_SCALE_DOWN_THRESHOLD = exports.LIFECYCLE_MIN_UPTIME = exports.LIFECYCLE_STARTUP_GRACE_PERIOD = exports.LIFECYCLE_EMPTY_TIMEOUT = exports.LIFECYCLE_CHECK_INTERVAL = exports.RABBITMQ_URL = void 0;
|
||||
exports.QUERY_PORT_START = exports.GAME_PORT_START = exports.DEFAULT_DESIRED_SERVERS = exports.LIFECYCLE_CRASH_RETENTION = exports.LIFECYCLE_CRASH_TIMEOUT = exports.LIFECYCLE_SCALE_COOLDOWN = exports.LIFECYCLE_STARTUP_GRACE_PERIOD = exports.LIFECYCLE_SCALE_DOWN_THRESHOLD = exports.LIFECYCLE_MIN_UPTIME = exports.LIFECYCLE_EMPTY_TIMEOUT = exports.LIFECYCLE_CHECK_INTERVAL = exports.RABBITMQ_URL = void 0;
|
||||
exports.RABBITMQ_URL = "amqp://manager:gigi1337@192.168.1.74";
|
||||
exports.LIFECYCLE_CHECK_INTERVAL = 10000;
|
||||
exports.LIFECYCLE_EMPTY_TIMEOUT = 300000;
|
||||
exports.LIFECYCLE_STARTUP_GRACE_PERIOD = 60000;
|
||||
exports.LIFECYCLE_MIN_UPTIME = 300000;
|
||||
exports.LIFECYCLE_SCALE_DOWN_THRESHOLD = 0.30;
|
||||
exports.LIFECYCLE_SCALE_COOLDOWN = 60000;
|
||||
exports.LIFECYCLE_CRASH_TIMEOUT = 30000;
|
||||
// Lifecycle
|
||||
exports.LIFECYCLE_CHECK_INTERVAL = 10000; // Alle 10 Sekunden prüfen
|
||||
// Scale Down
|
||||
exports.LIFECYCLE_EMPTY_TIMEOUT = 300000; // 5 Minuten leer
|
||||
exports.LIFECYCLE_MIN_UPTIME = 600000; // 10 Minuten Mindestlaufzeit
|
||||
exports.LIFECYCLE_SCALE_DOWN_THRESHOLD = 0.30; // Unter 30% Gesamtauslastung darf abgebaut werden
|
||||
// Scale Up
|
||||
exports.LIFECYCLE_STARTUP_GRACE_PERIOD = 60000; // 1 Minute Schutz nach Start
|
||||
exports.LIFECYCLE_SCALE_COOLDOWN = 120000; // 2 Minuten zwischen Scale-Up Aktionen
|
||||
// Crash Detection
|
||||
exports.LIFECYCLE_CRASH_TIMEOUT = 120000; // 2 Minuten ohne Status -> Crash
|
||||
exports.LIFECYCLE_CRASH_RETENTION = 300000; // 5 Minuten sichtbar nach Crash
|
||||
// Default
|
||||
exports.DEFAULT_DESIRED_SERVERS = 1;
|
||||
// Ports
|
||||
exports.GAME_PORT_START = 7777;
|
||||
exports.QUERY_PORT_START = 27015;
|
||||
|
||||
+18
-7
@@ -1,13 +1,24 @@
|
||||
export const RABBITMQ_URL = "amqp://manager:gigi1337@192.168.1.74";
|
||||
|
||||
export const LIFECYCLE_CHECK_INTERVAL = 10000;
|
||||
export const LIFECYCLE_EMPTY_TIMEOUT = 300000;
|
||||
export const LIFECYCLE_STARTUP_GRACE_PERIOD = 60000;
|
||||
export const LIFECYCLE_MIN_UPTIME = 300000;
|
||||
export const LIFECYCLE_SCALE_DOWN_THRESHOLD = 0.30;
|
||||
export const LIFECYCLE_SCALE_COOLDOWN = 60000;
|
||||
export const LIFECYCLE_CRASH_TIMEOUT = 30000;
|
||||
// Lifecycle
|
||||
export const LIFECYCLE_CHECK_INTERVAL = 10000; // Alle 10 Sekunden prüfen
|
||||
|
||||
// Scale Down
|
||||
export const LIFECYCLE_EMPTY_TIMEOUT = 300000; // 5 Minuten leer
|
||||
export const LIFECYCLE_MIN_UPTIME = 600000; // 10 Minuten Mindestlaufzeit
|
||||
export const LIFECYCLE_SCALE_DOWN_THRESHOLD = 0.30; // Unter 30% Gesamtauslastung darf abgebaut werden
|
||||
|
||||
// Scale Up
|
||||
export const LIFECYCLE_STARTUP_GRACE_PERIOD = 60000; // 1 Minute Schutz nach Start
|
||||
export const LIFECYCLE_SCALE_COOLDOWN = 120000; // 2 Minuten zwischen Scale-Up Aktionen
|
||||
|
||||
// Crash Detection
|
||||
export const LIFECYCLE_CRASH_TIMEOUT = 120000; // 2 Minuten ohne Status -> Crash
|
||||
export const LIFECYCLE_CRASH_RETENTION = 300000; // 5 Minuten sichtbar nach Crash
|
||||
|
||||
// Default
|
||||
export const DEFAULT_DESIRED_SERVERS = 1;
|
||||
|
||||
// Ports
|
||||
export const GAME_PORT_START = 7777;
|
||||
export const QUERY_PORT_START = 27015;
|
||||
|
||||
@@ -51,6 +51,19 @@ class ServerLifecycle {
|
||||
logger.info("Server RUNNING:", server.name, "PID:", server.pid);
|
||||
}
|
||||
break;
|
||||
case "RECOVERING":
|
||||
if (Date.now() -
|
||||
server.lastSeen
|
||||
>
|
||||
config_1.LIFECYCLE_CRASH_TIMEOUT) {
|
||||
server.status =
|
||||
"CRASHED";
|
||||
server.crashedAt =
|
||||
Date.now();
|
||||
this.serverRegistry.update(server);
|
||||
logger.error("Server-Recovery fehlgeschlagen:", server.name);
|
||||
}
|
||||
break;
|
||||
case "RUNNING":
|
||||
/*
|
||||
Crash Detection
|
||||
@@ -61,6 +74,8 @@ class ServerLifecycle {
|
||||
config_1.LIFECYCLE_CRASH_TIMEOUT) {
|
||||
server.status =
|
||||
"CRASHED";
|
||||
server.crashedAt =
|
||||
Date.now();
|
||||
this.serverRegistry.update(server);
|
||||
logger.error("Server abgestürzt:", server.name);
|
||||
break;
|
||||
@@ -92,7 +107,20 @@ class ServerLifecycle {
|
||||
}
|
||||
break;
|
||||
case "CRASHED":
|
||||
logger.error("Server abgestürzt erkannt:", server.name);
|
||||
if (!server.crashedAt) {
|
||||
server.crashedAt =
|
||||
Date.now();
|
||||
this.serverRegistry.update(server);
|
||||
logger.error("Server abgestürzt erkannt:", server.name);
|
||||
break;
|
||||
}
|
||||
if (Date.now() -
|
||||
server.crashedAt
|
||||
>
|
||||
config_1.LIFECYCLE_CRASH_RETENTION) {
|
||||
logger.info("Entferne abgestürzten Server nach Grace-Zeit:", server.name);
|
||||
this.serverRegistry.remove(server.id);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -102,7 +130,8 @@ class ServerLifecycle {
|
||||
const activeServers = this.serverRegistry
|
||||
.getAll()
|
||||
.filter(server => server.status === "RUNNING" ||
|
||||
server.status === "STARTING");
|
||||
server.status === "STARTING" ||
|
||||
server.status === "RECOVERING");
|
||||
/*
|
||||
SLOT AUSLASTUNG
|
||||
*/
|
||||
@@ -166,14 +195,14 @@ class ServerLifecycle {
|
||||
const activeCount = this.serverRegistry
|
||||
.getAll()
|
||||
.filter(s => s.status === "RUNNING" ||
|
||||
s.status === "STARTING")
|
||||
s.status === "STARTING" ||
|
||||
s.status === "RECOVERING")
|
||||
.length;
|
||||
if (activeCount <=
|
||||
this.desiredServers) {
|
||||
break;
|
||||
}
|
||||
logger.info("Stoppe leeren Server:", server.name);
|
||||
logger.info("Stoppe leeren Server:", server.name);
|
||||
this.serverManager.stopServer(server.id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
LIFECYCLE_SCALE_DOWN_THRESHOLD,
|
||||
LIFECYCLE_SCALE_COOLDOWN,
|
||||
LIFECYCLE_CRASH_TIMEOUT,
|
||||
LIFECYCLE_CRASH_RETENTION,
|
||||
DEFAULT_DESIRED_SERVERS
|
||||
} from "./config";
|
||||
|
||||
@@ -178,6 +179,9 @@ export class ServerLifecycle {
|
||||
server.status =
|
||||
"CRASHED";
|
||||
|
||||
server.crashedAt =
|
||||
Date.now();
|
||||
|
||||
|
||||
this.serverRegistry.update(
|
||||
server
|
||||
@@ -218,6 +222,9 @@ export class ServerLifecycle {
|
||||
server.status =
|
||||
"CRASHED";
|
||||
|
||||
server.crashedAt =
|
||||
Date.now();
|
||||
|
||||
|
||||
this.serverRegistry.update(
|
||||
server
|
||||
@@ -317,11 +324,42 @@ export class ServerLifecycle {
|
||||
case "CRASHED":
|
||||
|
||||
|
||||
if(!server.crashedAt){
|
||||
|
||||
logger.error(
|
||||
"Server abgestürzt erkannt:",
|
||||
server.name
|
||||
);
|
||||
server.crashedAt =
|
||||
Date.now();
|
||||
|
||||
this.serverRegistry.update(
|
||||
server
|
||||
);
|
||||
|
||||
logger.error(
|
||||
"Server abgestürzt erkannt:",
|
||||
server.name
|
||||
);
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
|
||||
if(
|
||||
Date.now() -
|
||||
server.crashedAt
|
||||
>
|
||||
LIFECYCLE_CRASH_RETENTION
|
||||
){
|
||||
|
||||
logger.info(
|
||||
"Entferne abgestürzten Server nach Grace-Zeit:",
|
||||
server.name
|
||||
);
|
||||
|
||||
this.serverRegistry.remove(
|
||||
server.id
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
|
||||
@@ -21,7 +21,7 @@ class ServerRegistry {
|
||||
port: serverData.port,
|
||||
queryPort: serverData.queryPort,
|
||||
created: serverData.created,
|
||||
status: "STARTING",
|
||||
status: "RECOVERING",
|
||||
players: 0,
|
||||
maxPlayers: 0,
|
||||
lastSeen: Date.now()
|
||||
@@ -96,9 +96,14 @@ class ServerRegistry {
|
||||
logger.debug("Server cleanly stopped:", server.name);
|
||||
this.remove(server.id);
|
||||
}
|
||||
else if (server.status === "RUNNING") {
|
||||
else if (server.status === "RUNNING" ||
|
||||
server.status === "RECOVERING") {
|
||||
server.status =
|
||||
"CRASHED";
|
||||
if (!server.crashedAt) {
|
||||
server.crashedAt =
|
||||
Date.now();
|
||||
}
|
||||
this.servers.set(server.id, server);
|
||||
logger.warn("Server crashed:", server.name);
|
||||
}
|
||||
@@ -117,7 +122,9 @@ class ServerRegistry {
|
||||
server.lastSeen =
|
||||
Date.now();
|
||||
const oldStatus = server.status;
|
||||
if (srv.alive) {
|
||||
if (srv.alive && server.status !== "STOPPING") {
|
||||
server.crashedAt =
|
||||
undefined;
|
||||
if (!server.startedAt) {
|
||||
server.startedAt =
|
||||
srv.started;
|
||||
@@ -125,9 +132,14 @@ class ServerRegistry {
|
||||
server.status =
|
||||
"RUNNING";
|
||||
}
|
||||
else if (server.status === "RUNNING") {
|
||||
else if (server.status === "RUNNING" ||
|
||||
server.status === "RECOVERING") {
|
||||
server.status =
|
||||
"CRASHED";
|
||||
if (!server.crashedAt) {
|
||||
server.crashedAt =
|
||||
Date.now();
|
||||
}
|
||||
}
|
||||
if (oldStatus !== server.status) {
|
||||
logger.debug("Status change:", server.name, oldStatus, "->", server.status);
|
||||
|
||||
@@ -42,6 +42,8 @@ export interface ServerInfo {
|
||||
|
||||
startedAt?:number;
|
||||
|
||||
crashedAt?:number;
|
||||
|
||||
lastSeen:number;
|
||||
|
||||
|
||||
@@ -357,6 +359,13 @@ export class ServerRegistry {
|
||||
server.status =
|
||||
"CRASHED";
|
||||
|
||||
if(!server.crashedAt){
|
||||
|
||||
server.crashedAt =
|
||||
Date.now();
|
||||
|
||||
}
|
||||
|
||||
|
||||
this.servers.set(
|
||||
server.id,
|
||||
@@ -416,6 +425,9 @@ export class ServerRegistry {
|
||||
|
||||
if(srv.alive && server.status !== "STOPPING"){
|
||||
|
||||
server.crashedAt =
|
||||
undefined;
|
||||
|
||||
if(!server.startedAt){
|
||||
|
||||
server.startedAt =
|
||||
@@ -435,6 +447,13 @@ export class ServerRegistry {
|
||||
server.status =
|
||||
"CRASHED";
|
||||
|
||||
if(!server.crashedAt){
|
||||
|
||||
server.crashedAt =
|
||||
Date.now();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -35,6 +35,8 @@ class ServerStatusManager {
|
||||
return;
|
||||
server.status =
|
||||
"RUNNING";
|
||||
server.crashedAt =
|
||||
undefined;
|
||||
if (!server.startedAt) {
|
||||
server.startedAt =
|
||||
Date.now();
|
||||
@@ -48,6 +50,10 @@ class ServerStatusManager {
|
||||
return;
|
||||
server.status =
|
||||
"CRASHED";
|
||||
if (!server.crashedAt) {
|
||||
server.crashedAt =
|
||||
Date.now();
|
||||
}
|
||||
this.registry.update(server);
|
||||
logger.info("Server stopped:", data.serverId);
|
||||
}
|
||||
|
||||
@@ -160,6 +160,9 @@ export class ServerStatusManager {
|
||||
server.status =
|
||||
"RUNNING";
|
||||
|
||||
server.crashedAt =
|
||||
undefined;
|
||||
|
||||
|
||||
if(!server.startedAt){
|
||||
|
||||
@@ -221,6 +224,13 @@ export class ServerStatusManager {
|
||||
server.status =
|
||||
"CRASHED";
|
||||
|
||||
if(!server.crashedAt){
|
||||
|
||||
server.crashedAt =
|
||||
Date.now();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -76,6 +76,7 @@ class WebApi {
|
||||
name: server.name,
|
||||
status: server.status,
|
||||
wrapperId: server.wrapperId,
|
||||
pid: server.pid,
|
||||
port: server.port,
|
||||
queryPort: server.queryPort,
|
||||
players: server.players,
|
||||
@@ -95,6 +96,7 @@ class WebApi {
|
||||
name: server.name,
|
||||
status: server.status,
|
||||
wrapperId: server.wrapperId,
|
||||
pid: server.pid,
|
||||
port: server.port,
|
||||
queryPort: server.queryPort,
|
||||
players: server.players,
|
||||
|
||||
+4
-1
@@ -6,5 +6,8 @@
|
||||
"wrapper",
|
||||
"shared",
|
||||
"dashboard"
|
||||
]
|
||||
],
|
||||
"allowScripts": {
|
||||
"esbuild@0.21.5": true
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user