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:
@@ -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);
|
||||
};
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user