diff --git a/src/backend/database/repositories/host-resolution-repository.ts b/src/backend/database/repositories/host-resolution-repository.ts index 811d23395..960a02971 100644 --- a/src/backend/database/repositories/host-resolution-repository.ts +++ b/src/backend/database/repositories/host-resolution-repository.ts @@ -1,4 +1,4 @@ -import { and, eq, inArray, isNotNull } from "drizzle-orm"; +import { and, eq, inArray, isNotNull, sql } from "drizzle-orm"; import { hosts, sshCredentials, sshFolders } from "../db/schema.js"; import type { DatabaseContext } from "./database-context.js"; import { DataCrypto } from "../../utils/data-crypto.js"; @@ -326,6 +326,7 @@ export class HostResolutionRepository { hostKeyAlgorithm: algorithm, hostKeyFirstSeen: now, hostKeyLastVerified: now, + updatedAt: sql`CURRENT_TIMESTAMP`, }) .where(eq(hosts.id, hostId)); await this.afterWrite(); @@ -347,6 +348,7 @@ export class HostResolutionRepository { hostKeyAlgorithm: algorithm, hostKeyLastVerified: now, hostKeyChangedCount: currentChangeCount + 1, + updatedAt: sql`CURRENT_TIMESTAMP`, }) .where(eq(hosts.id, hostId)); await this.afterWrite(); @@ -358,7 +360,7 @@ export class HostResolutionRepository { ): Promise { await this.context.drizzle .update(hosts) - .set({ hostKeyLastVerified: now }) + .set({ hostKeyLastVerified: now, updatedAt: sql`CURRENT_TIMESTAMP` }) .where(eq(hosts.id, hostId)); await (this.onLazyWrite?.() ?? this.afterWrite()); } diff --git a/src/ui/features/host-metrics/HostMetricsTab.tsx b/src/ui/features/host-metrics/HostMetricsTab.tsx index 837609732..9bad7b33c 100644 --- a/src/ui/features/host-metrics/HostMetricsTab.tsx +++ b/src/ui/features/host-metrics/HostMetricsTab.tsx @@ -373,7 +373,15 @@ function HostMetricsInner({ if (result.viewerSessionId) setViewerSessionId(result.viewerSessionId); } - const data = await getServerMetricsById(currentHostConfig.id); + // The connect above only opens the SSH session; the first real sample is + // collected asynchronously on the backend (status check, then metrics + // exec), so it isn't ready the instant the connection succeeds. Give it + // a few short retries before treating the initial fetch as a failure. + let data = await getServerMetricsById(currentHostConfig.id); + for (let i = 0; !data && i < 5; i++) { + await new Promise((resolve) => setTimeout(resolve, 1500)); + data = await getServerMetricsById(currentHostConfig.id); + } if (!data) { throw new Error(t("hostMetrics.connectionFailed")); }