Remove duplicate server detail metrics
This commit is contained in:
@@ -9,7 +9,6 @@ import type {
|
||||
JobResponse,
|
||||
ServerInstanceResponse,
|
||||
ServerMemberResponse,
|
||||
ServerMetricsResponse,
|
||||
ServerDeploymentResponse,
|
||||
ServerConfigDiffPreviewResponse,
|
||||
RunEndpointResponse,
|
||||
@@ -17,14 +16,13 @@ import type {
|
||||
ServerFileListResponse,
|
||||
ServerFileWorkspaceResponse
|
||||
} from "../api/types";
|
||||
import { ConfirmDialog, UsageMeter } from "../components/OperationControls";
|
||||
import { ConfirmDialog } from "../components/OperationControls";
|
||||
import { ServerManagementTerminalDrawer } from "../components/ServerManagementTerminalDrawer";
|
||||
import { EmptyState, ErrorState, LoadingState, ResultBadge } from "../components/StateViews";
|
||||
import type { PageComponentProps } from "../contracts/page";
|
||||
import { canStartServer, canStopServer, runtimeObservationFreshness, serverMetadataFormFromInstance, type ServerMetadataFormState } from "../contracts/serverManagement";
|
||||
import {
|
||||
serverDetailSections,
|
||||
serverIsOnline,
|
||||
type ConfigDiffView,
|
||||
type LlmSuggestionView,
|
||||
type ServerDetailSection
|
||||
@@ -41,14 +39,12 @@ import { PluginPageHostPage } from "./PluginPageHostPage";
|
||||
type LoadState<T> = { status: "loading" } | { status: "error"; reason: string } | { status: "ready"; data: T };
|
||||
|
||||
const serverDetailRefreshMs = 5000;
|
||||
const serverMetricFreshMs = 30000;
|
||||
|
||||
export function ServerDetailPage(props: PageComponentProps) {
|
||||
const { session, params, operations, onNavigate } = props;
|
||||
const serverId = params.serverId ?? "";
|
||||
const [section, setSection] = useState<ServerDetailSection>("manage");
|
||||
const [instance, setInstance] = useState<LoadState<ServerInstanceResponse>>({ status: "loading" });
|
||||
const [metrics, setMetrics] = useState<ServerMetricsResponse | null>(null);
|
||||
const [plugins, setPlugins] = useState<GamePluginResponse[]>([]);
|
||||
const [jobs, setJobs] = useState<JobResponse[]>([]);
|
||||
const [runEndpoint, setRunEndpoint] = useState<RunEndpointResponse | undefined>();
|
||||
@@ -84,12 +80,6 @@ export function ServerDetailPage(props: PageComponentProps) {
|
||||
setRunEndpoint(undefined);
|
||||
setDeployment({ status: "error", reason: "部署定义加载失败" });
|
||||
}
|
||||
try {
|
||||
const metricsResponse = await platformApiClient.listServerMetrics();
|
||||
setMetrics(metricsResponse.items.find((item) => item.serverInstanceId === serverId) ?? null);
|
||||
} catch {
|
||||
setMetrics(null);
|
||||
}
|
||||
}, [serverId]);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -99,18 +89,16 @@ export function ServerDetailPage(props: PageComponentProps) {
|
||||
const refreshOperationalState = useCallback(async () => {
|
||||
if (!serverId) return;
|
||||
try {
|
||||
const [detail, jobResponse, metricsResponse, endpointResponse] = await Promise.all([
|
||||
const [detail, jobResponse, endpointResponse] = await Promise.all([
|
||||
platformApiClient.getServerInstance(serverId),
|
||||
platformApiClient.listJobs(serverId),
|
||||
platformApiClient.listServerMetrics(),
|
||||
platformApiClient.listRunEndpoints()
|
||||
]);
|
||||
setInstance({ status: "ready", data: detail });
|
||||
setJobs(jobResponse.items);
|
||||
setMetrics(metricsResponse.items.find((item) => item.serverInstanceId === serverId) ?? null);
|
||||
setRunEndpoint(endpointResponse.items.find((endpoint) => endpoint.id === detail.runEndpointId));
|
||||
} catch {
|
||||
setMetrics(null);
|
||||
setRunEndpoint(undefined);
|
||||
}
|
||||
}, [serverId]);
|
||||
|
||||
@@ -124,7 +112,6 @@ export function ServerDetailPage(props: PageComponentProps) {
|
||||
const detailFreshness = instance.status === "ready" ? runtimeObservationFreshness(instance.data, runEndpoint) : "unverified";
|
||||
const detailStateText = instance.status === "ready" && detailFreshness === "fresh" ? stateLabel(instance.data.state) : instance.status === "ready" ? `最后观测:${stateLabel(instance.data.state)}(Run 未验证)` : "未验证";
|
||||
const detailSections = useMemo(() => serverDetailSectionEntries(readyPlugin), [readyPlugin]);
|
||||
const metricsWaiting = metrics?.source === "run-metrics-pending";
|
||||
|
||||
useEffect(() => {
|
||||
if (!params.routeKey || !readyPlugin?.pages.some((page) => page.key === params.routeKey)) return;
|
||||
@@ -247,18 +234,6 @@ export function ServerDetailPage(props: PageComponentProps) {
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="server-detail-stat-strip">
|
||||
<HeaderStat label="状态" value={detailFreshness === "fresh" ? (serverIsOnline(instance.data.state) ? "在线" : "离线") : "未验证"} />
|
||||
<HeaderStat label="玩家" value={metrics?.playerCount !== undefined ? `${metrics.playerCount}${metrics.maxPlayers ? `/${metrics.maxPlayers}` : ""}` : "--"} />
|
||||
<HeaderStat label="TPS" value={metrics?.tps !== undefined ? metrics.tps.toFixed(1) : "--"} />
|
||||
<HeaderStat label="延迟" value={metrics?.latencyMs !== undefined ? `${Math.round(metrics.latencyMs)}ms` : "--"} />
|
||||
<HeaderStat label="指标" value={metricFreshnessLabel(metrics)} />
|
||||
</div>
|
||||
<div className="server-detail-meter-strip">
|
||||
<UsageMeter label="CPU" percent={metrics?.cpuPercent} pending={metricsWaiting} />
|
||||
<UsageMeter label="内存" percent={metrics?.memoryPercent} pending={metricsWaiting} />
|
||||
<UsageMeter label="磁盘" percent={metrics?.diskPercent} pending={metricsWaiting} />
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<nav className="section-tabs" aria-label="server sections">
|
||||
@@ -886,22 +861,6 @@ function formatDateTime(value?: string): string {
|
||||
return Number.isNaN(parsed.getTime()) ? value : parsed.toLocaleString();
|
||||
}
|
||||
|
||||
function HeaderStat({ label, value }: { label: string; value: string }) {
|
||||
return (
|
||||
<span className="server-card-stat">
|
||||
<span>{label}</span>
|
||||
<strong>{value}</strong>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
function metricFreshnessLabel(metrics: ServerMetricsResponse | null): string {
|
||||
if (!metrics || metrics.source === "run-metrics-pending") return "等待上报";
|
||||
const collectedAt = new Date(metrics.collectedAt).getTime();
|
||||
if (Number.isFinite(collectedAt) && Date.now() - collectedAt > serverMetricFreshMs) return "指标过期";
|
||||
return new Date(metrics.collectedAt).toLocaleTimeString();
|
||||
}
|
||||
|
||||
interface LlmSectionProps {
|
||||
serverId: string;
|
||||
instance: ServerInstanceResponse;
|
||||
|
||||
Reference in New Issue
Block a user