Files
Toju/toju-app/src/app/domains/server-directory/infrastructure/services/server-endpoint-health.service.ts
2026-06-05 06:16:02 +02:00

86 lines
2.6 KiB
TypeScript

import { Injectable, inject } from '@angular/core';
import { SERVER_HEALTH_CHECK_TIMEOUT_MS } from '../constants/server-directory.infrastructure.constants';
import type {
ServerEndpoint,
ServerEndpointHealthResult,
ServerHealthCheckPayload
} from '../../domain/models/server-directory.model';
import { ServerEndpointCompatibilityService } from './server-endpoint-compatibility.service';
@Injectable({ providedIn: 'root' })
export class ServerEndpointHealthService {
private readonly endpointCompatibility = inject(ServerEndpointCompatibilityService);
async probeEndpoint(
endpoint: Pick<ServerEndpoint, 'url'>,
clientVersion: string | null
): Promise<ServerEndpointHealthResult> {
const startTime = Date.now();
try {
const response = await fetch(`${endpoint.url}/api/health`, {
method: 'GET',
signal: AbortSignal.timeout(SERVER_HEALTH_CHECK_TIMEOUT_MS)
});
const latency = Date.now() - startTime;
if (response.ok) {
const payload = await response.json() as ServerHealthCheckPayload;
const versionCompatibility = this.endpointCompatibility.evaluateServerVersion(
payload.serverVersion,
clientVersion
);
const serverInstanceId = typeof payload.serverInstanceId === 'string' && payload.serverInstanceId.trim().length > 0
? payload.serverInstanceId.trim()
: undefined;
const serverTag = typeof payload.serverTag === 'string' && payload.serverTag.trim().length > 0
? payload.serverTag.trim()
: undefined;
if (!versionCompatibility.isCompatible) {
return {
status: 'incompatible',
latency,
serverTag,
versions: {
serverInstanceId,
serverVersion: versionCompatibility.serverVersion,
clientVersion
}
};
}
return {
status: 'online',
latency,
serverTag,
versions: {
serverInstanceId,
serverVersion: versionCompatibility.serverVersion,
clientVersion
}
};
}
return { status: 'offline' };
} catch {
try {
const response = await fetch(`${endpoint.url}/api/servers`, {
method: 'GET',
signal: AbortSignal.timeout(SERVER_HEALTH_CHECK_TIMEOUT_MS)
});
const latency = Date.now() - startTime;
if (response.ok) {
return {
status: 'online',
latency
};
}
} catch { /* both checks failed */ }
return { status: 'offline' };
}
}
}