Skip to content

Commit

Permalink
feat(stats): shows ephemeral and persistent storage separately on pie…
Browse files Browse the repository at this point in the history
… chart

refs #645
  • Loading branch information
stalniy committed Jan 16, 2025
1 parent c5efbff commit 7c23b28
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 64 deletions.
8 changes: 7 additions & 1 deletion apps/api/src/routes/v1/networkCapacity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,13 @@ const route = createRoute({
totalCPU: z.number(),
totalGPU: z.number(),
totalMemory: z.number(),
totalStorage: z.number()
totalStorage: z.number(),
activeEphemeralStorage: z.number(),
pendingEphemeralStorage: z.number(),
availableEphemeralStorage: z.number(),
activePersistentStorage: z.number(),
pendingPersistentStorage: z.number(),
availablePersistentStorage: z.number(),
})
}
}
Expand Down
74 changes: 52 additions & 22 deletions apps/api/src/services/db/providerStatusService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,31 +24,61 @@ export async function getNetworkCapacity() {
]
});

const filteredProviders = providers.filter((value, index, self) => self.map(x => x.hostUri).indexOf(value.hostUri) === index);
const seenHostUris = new Set<string>();
const filteredProviders = providers.filter((provider) => {
if (seenHostUris.has(provider.hostUri)) return false;
seenHostUris.add(provider.hostUri);
return true;
});

const stats = {
activeProviderCount: filteredProviders.length,
activeCPU: filteredProviders.map(x => x.lastSuccessfulSnapshot.activeCPU).reduce((a, b) => a + b, 0),
activeGPU: filteredProviders.map(x => x.lastSuccessfulSnapshot.activeGPU).reduce((a, b) => a + b, 0),
activeMemory: filteredProviders.map(x => x.lastSuccessfulSnapshot.activeMemory).reduce((a, b) => a + b, 0),
activeStorage: filteredProviders
.map(x => x.lastSuccessfulSnapshot.activeEphemeralStorage + x.lastSuccessfulSnapshot.activePersistentStorage)
.reduce((a, b) => a + b, 0),
pendingCPU: filteredProviders.map(x => x.lastSuccessfulSnapshot.pendingCPU).reduce((a, b) => a + b, 0),
pendingGPU: filteredProviders.map(x => x.lastSuccessfulSnapshot.pendingGPU).reduce((a, b) => a + b, 0),
pendingMemory: filteredProviders.map(x => x.lastSuccessfulSnapshot.pendingMemory).reduce((a, b) => a + b, 0),
pendingStorage: filteredProviders
.map(x => x.lastSuccessfulSnapshot.pendingEphemeralStorage + x.lastSuccessfulSnapshot.pendingPersistentStorage)
.reduce((a, b) => a + b, 0),
availableCPU: filteredProviders.map(x => x.lastSuccessfulSnapshot.availableCPU).reduce((a, b) => a + b, 0),
availableGPU: filteredProviders.map(x => x.lastSuccessfulSnapshot.availableGPU).reduce((a, b) => a + b, 0),
availableMemory: filteredProviders.map(x => x.lastSuccessfulSnapshot.availableMemory).reduce((a, b) => a + b, 0),
availableStorage: filteredProviders
.map(x => x.lastSuccessfulSnapshot.availableEphemeralStorage + x.lastSuccessfulSnapshot.availablePersistentStorage)
.reduce((a, b) => a + b, 0)
};
const stats = filteredProviders.reduce((all, provider) => {
stats.activeCPU += provider.lastSuccessfulSnapshot.activeCPU;
stats.pendingCPU += provider.lastSuccessfulSnapshot.pendingCPU;
stats.availableCPU += provider.lastSuccessfulSnapshot.availableCPU;

stats.activeGPU += provider.lastSuccessfulSnapshot.activeGPU;
stats.pendingGPU += provider.lastSuccessfulSnapshot.pendingGPU;
stats.availableGPU += provider.lastSuccessfulSnapshot.availableGPU;

stats.activeMemory += provider.lastSuccessfulSnapshot.activeMemory;
stats.pendingMemory += provider.lastSuccessfulSnapshot.pendingMemory;
stats.availableMemory += provider.lastSuccessfulSnapshot.availableMemory;

stats.activeEphemeralStorage += provider.lastSuccessfulSnapshot.activeEphemeralStorage;
stats.pendingEphemeralStorage += provider.lastSuccessfulSnapshot.pendingEphemeralStorage;
stats.availableEphemeralStorage += provider.lastSuccessfulSnapshot.availableEphemeralStorage;

stats.activePersistentStorage += provider.lastSuccessfulSnapshot.activePersistentStorage;
stats.pendingPersistentStorage += provider.lastSuccessfulSnapshot.pendingPersistentStorage;
stats.availablePersistentStorage += provider.lastSuccessfulSnapshot.availablePersistentStorage;

return all;
}, {
activeCPU: 0,
pendingCPU: 0,
availableCPU: 0,
activeGPU: 0,
pendingGPU: 0,
availableGPU: 0,
activeMemory: 0,
pendingMemory: 0,
availableMemory: 0,
activeStorage: 0,
pendingStorage: 0,
availableStorage: 0,
activeEphemeralStorage: 0,
pendingEphemeralStorage: 0,
availableEphemeralStorage: 0,
activePersistentStorage: 0,
pendingPersistentStorage: 0,
availablePersistentStorage: 0,
});

return {
activeProviderCount: filteredProviders.length,
activeStorage: stats.activeEphemeralStorage + stats.activePersistentStorage,
pendingStorage: stats.pendingEphemeralStorage + stats.pendingPersistentStorage,
availableStorage: stats.availableEphemeralStorage + stats.availablePersistentStorage,
...stats,
totalCPU: stats.activeCPU + stats.pendingCPU + stats.availableCPU,
totalGPU: stats.activeGPU + stats.pendingGPU + stats.availableGPU,
Expand Down
99 changes: 72 additions & 27 deletions apps/deploy-web/src/components/providers/NetworkCapacity.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"use client";
import { useIntl } from "react-intl";
import { ResponsivePie } from "@nivo/pie";
import { ResponsivePie, ComputedDatum } from "@nivo/pie";
import {BasicTooltip} from '@nivo/tooltip';
import { useTheme } from "next-themes";

import useTailwind from "@src/hooks/useTailwind";
Expand All @@ -20,22 +21,29 @@ type Props = {
activeStorage: number;
pendingStorage: number;
totalStorage: number;
"activeEphemeralStorage": number;
"pendingEphemeralStorage": number;
"availableEphemeralStorage": number;
"activePersistentStorage": number;
"pendingPersistentStorage": number;
"availablePersistentStorage": number;
};

const NetworkCapacity: React.FunctionComponent<Props> = ({
activeCPU,
pendingCPU,
totalCPU,
activeGPU,
pendingGPU,
totalGPU,
activeMemory,
pendingMemory,
totalMemory,
activeStorage,
pendingStorage,
totalStorage
}) => {
const NetworkCapacity: React.FunctionComponent<Props> = (props) => {
const {
activeCPU,
pendingCPU,
totalCPU,
activeGPU,
pendingGPU,
totalGPU,
activeMemory,
pendingMemory,
totalMemory,
activeStorage,
pendingStorage,
totalStorage
} = props;
const { resolvedTheme } = useTheme();
const tw = useTailwind();
const activeMemoryBytes = activeMemory + pendingMemory;
Expand All @@ -51,21 +59,17 @@ const NetworkCapacity: React.FunctionComponent<Props> = ({
const cpuData = useData(activeCPU + pendingCPU, totalCPU - activeCPU - pendingCPU);
const gpuData = useData(activeGPU + pendingGPU, totalGPU - activeGPU - pendingGPU);
const memoryData = useData(activeMemoryBytes, availableMemoryBytes);
const storageData = useData(activeStorageBytes, availableStorageBytes);
const storageData = useStorageData(props);
const pieTheme = usePieTheme();
const intl = useIntl();

const _getColor = bar => getColor(bar.id);
const _getColor = (datum: ComputedDatum<{ color: string }>) => colors[datum.data.color] || colors[datum.id];

const colors = {
active: tw.theme.colors["primary"].DEFAULT,
available: resolvedTheme === "dark" ? tw.theme.colors.neutral[800] : tw.theme.colors.neutral[500]
};

const getColor = (id: string) => {
return colors[id];
};

return (
<div className="flex flex-col items-start md:flex-row md:items-center">
<div className="basis-1/4">
Expand Down Expand Up @@ -97,6 +101,7 @@ const NetworkCapacity: React.FunctionComponent<Props> = ({
enableArcLinkLabels={false}
arcLabelsSkipAngle={10}
theme={pieTheme}
tooltip={TooltipLabel}
/>
</div>
</div>
Expand Down Expand Up @@ -129,6 +134,7 @@ const NetworkCapacity: React.FunctionComponent<Props> = ({
enableArcLinkLabels={false}
arcLabelsSkipAngle={10}
theme={pieTheme}
tooltip={TooltipLabel}
/>
</div>
</div>
Expand Down Expand Up @@ -160,6 +166,7 @@ const NetworkCapacity: React.FunctionComponent<Props> = ({
enableArcLinkLabels={false}
arcLabelsSkipAngle={10}
theme={pieTheme}
tooltip={TooltipLabel}
/>
</div>
</div>
Expand All @@ -183,14 +190,14 @@ const NetworkCapacity: React.FunctionComponent<Props> = ({
from: "color",
modifiers: [["darker", 0.2]]
}}
valueFormat={value =>
value === activeStorageBytes
? `${roundDecimal(_activeStorage.value, 2)} ${_activeStorage.unit}`
: `${roundDecimal(_availableStorage.value, 2)} ${_availableStorage.unit}`
}
valueFormat={value => {
const formatted = bytesToShrink(value);
return `${roundDecimal(formatted.value, 2)} ${formatted.unit}`;
}}
enableArcLinkLabels={false}
arcLabelsSkipAngle={10}
theme={pieTheme}
tooltip={TooltipLabel}
/>
</div>
</div>
Expand Down Expand Up @@ -219,6 +226,35 @@ const useData = (active: number, available: number) => {
];
};

function useStorageData(storage: Pick<Props, 'activeEphemeralStorage' | 'availableEphemeralStorage' | 'activePersistentStorage' | 'availablePersistentStorage'>) {
return [
{
id: "active-ephemeral",
label: "Active emphemeral",
color: 'active',
value: storage.activeEphemeralStorage,
},
{
id: "available-emphemeral",
label: "Available emphemeral",
color: 'available',
value: storage.availableEphemeralStorage,
},
{
id: "active-persistent",
label: "Active persistent",
color: 'active',
value: storage.activePersistentStorage,
},
{
id: "available-persistent",
label: "Available persistent",
color: 'available',
value: storage.availablePersistentStorage,
}
];
}

const usePieTheme = () => {
const { resolvedTheme } = useTheme();
const tw = useTailwind();
Expand All @@ -232,10 +268,19 @@ const usePieTheme = () => {
color: resolvedTheme === "dark" ? tw.theme.colors.white : tw.theme.colors.current
},
container: {
backgroundColor: resolvedTheme === "dark" ? tw.theme.colors.neutral[700] : tw.theme.colors.white
backgroundColor: resolvedTheme === "dark" ? tw.theme.colors.neutral[700] : tw.theme.colors.white,
}
}
};
};

const TooltipLabel = <R,>({ datum }: { datum: ComputedDatum<R> }) => (
<BasicTooltip
id={datum.label}
value={datum.formattedValue}
enableChip={true}
color={datum.color}
/>
)

export default NetworkCapacity;
15 changes: 1 addition & 14 deletions apps/deploy-web/src/components/providers/ProviderList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -200,20 +200,7 @@ export const ProviderList: React.FunctionComponent = () => {

{providers && networkCapacity && (
<div className="mb-8">
<NetworkCapacity
activeCPU={networkCapacity.activeCPU}
pendingCPU={networkCapacity.pendingCPU}
totalCPU={networkCapacity.totalCPU}
activeGPU={networkCapacity.activeGPU}
pendingGPU={networkCapacity.pendingGPU}
totalGPU={networkCapacity.totalGPU}
activeMemory={networkCapacity.activeMemory}
pendingMemory={networkCapacity.pendingMemory}
totalMemory={networkCapacity.totalMemory}
activeStorage={networkCapacity.activeStorage}
pendingStorage={networkCapacity.pendingStorage}
totalStorage={networkCapacity.totalStorage}
/>
<NetworkCapacity {...networkCapacity} />
</div>
)}

Expand Down

0 comments on commit 7c23b28

Please sign in to comment.