feat: live docker/database widgets over WebSocket (M2)
Adds a custom server.ts (http server + Next request handler + a noServer:true WebSocket server on /ws) so the app can push live data without polling. A CollectorScheduler runs one interval-based job per docker/database widget instance, backed by dockerode against /var/run/docker.sock, and reconciles jobs when config.yml changes. Config hot-reload is now fully wired: chokidar watches config.yml/.env, re-validates on change, and broadcasts config:update (or a non-destructive config:error, keeping the last-good config) to every connected browser. The client subscribes to per-widget topics over a single shared WebSocket with exponential-backoff reconnect and last-result caching for instant resubscribe. Verified end-to-end against real throwaway containers (nginx, redis): live CPU/mem/uptime/health streamed over the socket, interval changes picked up without a server restart, and a broken config.yml correctly falls back to the last-valid config instead of crashing the app.
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
import type { DockerContainerResult } from "@/lib/types/widget-result";
|
||||
|
||||
interface Props {
|
||||
status?: DockerContainerResult["status"];
|
||||
health?: DockerContainerResult["health"];
|
||||
}
|
||||
|
||||
function resolveColorClass(status?: Props["status"], health?: Props["health"]): string {
|
||||
if (!status) return "bg-fg-muted";
|
||||
if (health === "unhealthy") return "bg-status-down";
|
||||
if (health === "starting") return "bg-status-degraded";
|
||||
if (status === "running") return "bg-status-up";
|
||||
if (status === "restarting") return "bg-status-degraded";
|
||||
return "bg-status-down";
|
||||
}
|
||||
|
||||
export function StatusDot({ status, health }: Props) {
|
||||
const label = status ? `${status}${health && health !== "none" ? ` (${health})` : ""}` : "unknown";
|
||||
|
||||
return (
|
||||
<span
|
||||
className={`h-2.5 w-2.5 shrink-0 rounded-full ${resolveColorClass(status, health)}`}
|
||||
title={label}
|
||||
/>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user