fix: resolve ERR_INSUFFICIENT_RESOURCES connection exhaustion

- Add concurrency limiter (max 4 GET requests) to API layer, leaving
  slots for SSE and health checks. Write ops bypass the limiter.
- Add AbortController to ContainerStats, project detail page, and
  dashboard to cancel in-flight requests on navigation/unmount.
- Move global SSE connection from layout to events page (only consumer).
- Add 30s heartbeat to SSE endpoint to detect zombie connections.
- Serialize dashboard project fetches to avoid parallel burst.
- Rebuild frontend in dev-server.sh so go:embed stays in sync.
This commit is contained in:
2026-04-13 00:12:14 +03:00
parent 791cd4d6af
commit 96fd910603
7 changed files with 233 additions and 87 deletions
+11 -16
View File
@@ -18,24 +18,19 @@
let error = $state(false);
$effect(() => {
let cancelled = false;
let inflight = false;
let controller = new AbortController();
async function load() {
if (inflight) return; // Skip if previous request still pending.
inflight = true;
// Abort any previous in-flight request before starting a new one.
controller.abort();
controller = new AbortController();
try {
const result = await api.fetchContainerStats(projectId, stageId, instanceId);
if (!cancelled) {
stats = result;
error = false;
}
} catch {
if (!cancelled) {
error = true;
}
} finally {
inflight = false;
const result = await api.fetchContainerStats(projectId, stageId, instanceId, controller.signal);
stats = result;
error = false;
} catch (e) {
if (e instanceof DOMException && e.name === 'AbortError') return;
error = true;
}
}
@@ -45,7 +40,7 @@
const interval = setInterval(load, 30_000);
return () => {
cancelled = true;
controller.abort();
clearInterval(interval);
};
});