Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
166 changes: 80 additions & 86 deletions apps/web/src/components/settings/ResourceTelemetryDiagnostics.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import type {
} from "@t3tools/contracts";
import * as DateTime from "effect/DateTime";
import * as Option from "effect/Option";
import { useCallback, useEffect, useMemo, useRef, useState, type ReactNode } from "react";
import { useEffect, useRef, useState, type ReactNode } from "react";
import {
isAtomCommandInterrupted,
squashAtomCommandFailure,
Expand Down Expand Up @@ -544,11 +544,8 @@ function ProcessTable({
onSignal: (process: ResourceTelemetryProcess, signal: ServerProcessSignal) => void;
}) {
const [collapsed, setCollapsed] = useState<ReadonlySet<string>>(() => new Set());
const visible = useMemo(
() => visibleResourceTelemetryProcesses(processes, collapsed),
[collapsed, processes],
);
const toggle = useCallback((process: ResourceTelemetryProcess) => {
const visible = visibleResourceTelemetryProcesses(processes, collapsed);
const toggle = (process: ResourceTelemetryProcess) => {
const identityKey = processIdentityKey(process);
setCollapsed((current) => {
const next = new Set(current);
Expand All @@ -559,7 +556,7 @@ function ProcessTable({
}
return next;
});
}, []);
};

return (
<div className="border-t border-border/60">
Expand Down Expand Up @@ -845,92 +842,89 @@ export function ResourceTelemetryDiagnostics({
const snapshot = telemetry.data;
const allT3 = snapshot?.groups.allT3;

const signalProcess = useCallback(
async (process: ResourceTelemetryProcess, signal: ServerProcessSignal) => {
const targetEnvironmentId = environmentIdRef.current;
if (
targetEnvironmentId === null ||
!readEnvironmentScope(targetEnvironmentId, AuthEnvironmentMaintainScope)
)
return;
const identityKey = processIdentityKey(process);
if (signalingKeysRef.current.has(identityKey)) return;
const nextSignalingKeys = new Set(signalingKeysRef.current).add(identityKey);
signalingKeysRef.current = nextSignalingKeys;
setSignalingKeys(nextSignalingKeys);
const clearSignaling = () => {
const next = new Set(signalingKeysRef.current);
next.delete(identityKey);
signalingKeysRef.current = next;
setSignalingKeys(next);
};
const signalProcess = async (process: ResourceTelemetryProcess, signal: ServerProcessSignal) => {
const targetEnvironmentId = environmentIdRef.current;
if (
targetEnvironmentId === null ||
!readEnvironmentScope(targetEnvironmentId, AuthEnvironmentMaintainScope)
)
return;
const identityKey = processIdentityKey(process);
if (signalingKeysRef.current.has(identityKey)) return;
const nextSignalingKeys = new Set(signalingKeysRef.current).add(identityKey);
signalingKeysRef.current = nextSignalingKeys;
setSignalingKeys(nextSignalingKeys);
const clearSignaling = () => {
const next = new Set(signalingKeysRef.current);
next.delete(identityKey);
signalingKeysRef.current = next;
setSignalingKeys(next);
};

if (signal === "SIGKILL") {
let confirmed = false;
try {
confirmed = await ensureLocalApi().dialogs.confirm(
`Send SIGKILL to process ${process.identity.pid}? This cannot be handled by the process.`,
{ variant: "destructive" },
);
} catch (error) {
clearSignaling();
toastManager.add({
type: "error",
title: "Could not confirm signal",
description: error instanceof Error ? error.message : `Failed to send ${signal}.`,
});
return;
}
if (!confirmed) {
clearSignaling();
return;
}
if (signal === "SIGKILL") {
let confirmed = false;
try {
confirmed = await ensureLocalApi().dialogs.confirm(
`Send SIGKILL to process ${process.identity.pid}? This cannot be handled by the process.`,
{ variant: "destructive" },
);
} catch (error) {
clearSignaling();
toastManager.add({
type: "error",
title: "Could not confirm signal",
description: error instanceof Error ? error.message : `Failed to send ${signal}.`,
});
return;
}
if (
environmentIdRef.current !== targetEnvironmentId ||
!readEnvironmentScope(targetEnvironmentId, AuthEnvironmentMaintainScope)
) {
if (!confirmed) {
clearSignaling();
return;
}
void signalServerProcess({
environmentId: targetEnvironmentId,
input: {
pid: process.identity.pid,
startTimeMs: process.identity.startTimeMs,
signal,
},
}
if (
environmentIdRef.current !== targetEnvironmentId ||
!readEnvironmentScope(targetEnvironmentId, AuthEnvironmentMaintainScope)
) {
clearSignaling();
return;
}
void signalServerProcess({
environmentId: targetEnvironmentId,
input: {
pid: process.identity.pid,
startTimeMs: process.identity.startTimeMs,
signal,
},
})
.then((result) => {
if (result._tag === "Failure") {
if (isAtomCommandInterrupted(result)) return;
throw squashAtomCommandFailure(result);
}
if (result.value.signaled) return;
toastManager.add({
type: "error",
title: `Could not send ${signal}`,
description: Option.getOrElse(
result.value.message,
() => `Failed to send ${signal} to process ${process.identity.pid}.`,
),
});
})
.then((result) => {
if (result._tag === "Failure") {
if (isAtomCommandInterrupted(result)) return;
throw squashAtomCommandFailure(result);
}
if (result.value.signaled) return;
toastManager.add({
type: "error",
title: `Could not send ${signal}`,
description: Option.getOrElse(
result.value.message,
() => `Failed to send ${signal} to process ${process.identity.pid}.`,
),
});
})
.catch((error: unknown) => {
toastManager.add({
type: "error",
title: `Could not send ${signal}`,
description: error instanceof Error ? error.message : `Failed to send ${signal}.`,
});
})
.finally(() => {
clearSignaling();
.catch((error: unknown) => {
toastManager.add({
type: "error",
title: `Could not send ${signal}`,
description: error instanceof Error ? error.message : `Failed to send ${signal}.`,
});
},
[signalServerProcess],
);
})
.finally(() => {
clearSignaling();
});
};

const retryCollector = useCallback(() => {
const retryCollector = () => {
const environmentId = environmentIdRef.current;
if (
environmentId === null ||
Expand All @@ -950,7 +944,7 @@ export function ResourceTelemetryDiagnostics({
.finally(() => {
setIsRetrying(false);
});
}, [retryTelemetry]);
};

const speedLimit = snapshot ? Option.getOrNull(snapshot.speedLimitPercent) : null;
const collectorNeedsRetry = shouldShowResourceMonitorRetry({
Expand Down
Loading