-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Closes MIS-244 ![image](https://github.com/user-attachments/assets/59aa72c4-ec9a-406c-92aa-644055cc8235) ![image](https://github.com/user-attachments/assets/a0ac0309-b2f9-4e34-87c4-fdbd50b6c53b) https://github.com/user-attachments/assets/0271281a-4e9c-466f-96d5-84ba43641c8f
- Loading branch information
Showing
12 changed files
with
791 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
101 changes: 101 additions & 0 deletions
101
apps/hub/src/domains/game/components/game-matchmaker/lobby-cpu-stats.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
import type { Rivet } from "@rivet-gg/api"; | ||
import { | ||
type ChartConfig, | ||
ChartContainer, | ||
ChartTooltip, | ||
ChartTooltipContent, | ||
timing, | ||
} from "@rivet-gg/components"; | ||
import { format } from "date-fns"; | ||
import { useId } from "react"; | ||
import { Area, AreaChart, CartesianGrid, XAxis, YAxis } from "recharts"; | ||
|
||
interface LobbyCPUStatsProps extends Pick<Rivet.cloud.SvcMetrics, "cpu"> { | ||
metricsAt: number; | ||
syncId?: string; | ||
} | ||
|
||
const chartConfig = { | ||
value: { | ||
color: "hsl(var(--chart-1))", | ||
label: "CPU Usage", | ||
}, | ||
} satisfies ChartConfig; | ||
|
||
export function LobbyCPUStats({ cpu, metricsAt, syncId }: LobbyCPUStatsProps) { | ||
const data = cpu.map((value, i) => ({ | ||
x: `${(cpu.length - i) * -15}`, | ||
value: value / 100, | ||
config: { | ||
label: new Date(metricsAt - (cpu.length - i) * timing.seconds(15)), | ||
}, | ||
})); | ||
|
||
const id = useId(); | ||
|
||
const fillId = `fill-${id}`; | ||
return ( | ||
<ChartContainer config={chartConfig}> | ||
<AreaChart accessibilityLayer data={data} syncId={syncId}> | ||
<CartesianGrid vertical={true} /> | ||
<XAxis | ||
interval="preserveStartEnd" | ||
dataKey="x" | ||
hide | ||
axisLine={false} | ||
domain={[0, 60]} | ||
tickCount={60} | ||
/> | ||
<YAxis | ||
dataKey="value" | ||
axisLine={false} | ||
padding={{ top: 10 }} | ||
domain={([, dataMax]) => { | ||
return [0, Math.ceil(dataMax * 100) / 100]; | ||
}} | ||
tickFormatter={(value) => `${value * 100}%`} | ||
/> | ||
<ChartTooltip | ||
content={ | ||
<ChartTooltipContent | ||
hideIndicator | ||
labelKey="label" | ||
labelFormatter={(label) => { | ||
return format(label, "HH:mm:ss"); | ||
}} | ||
valueFormatter={(value) => { | ||
if (typeof value !== "number") { | ||
return "n/a"; | ||
} | ||
return `${(value * 100).toFixed(2)}%`; | ||
}} | ||
/> | ||
} | ||
/> | ||
<defs> | ||
<linearGradient id={fillId} x1="0" y1="0" x2="0" y2="1"> | ||
<stop | ||
offset="5%" | ||
stopColor="var(--color-value)" | ||
stopOpacity={0.8} | ||
/> | ||
<stop | ||
offset="95%" | ||
stopColor="var(--color-value)" | ||
stopOpacity={0.1} | ||
/> | ||
</linearGradient> | ||
</defs> | ||
<Area | ||
isAnimationActive={false} | ||
dataKey="value" | ||
type="linear" | ||
fill={`url(#${fillId})`} | ||
fillOpacity={0.4} | ||
stroke="var(--color-value)" | ||
stackId="a" | ||
/> | ||
</AreaChart> | ||
</ChartContainer> | ||
); | ||
} |
109 changes: 109 additions & 0 deletions
109
apps/hub/src/domains/game/components/game-matchmaker/lobby-memory-stats.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
import type { Rivet } from "@rivet-gg/api"; | ||
import { | ||
type ChartConfig, | ||
ChartContainer, | ||
ChartTooltip, | ||
ChartTooltipContent, | ||
timing, | ||
} from "@rivet-gg/components"; | ||
import { format } from "date-fns"; | ||
import { filesize } from "filesize"; | ||
import { useId } from "react"; | ||
import { Area, AreaChart, CartesianGrid, XAxis, YAxis } from "recharts"; | ||
|
||
interface LobbyMemoryStatsProps | ||
extends Pick<Rivet.cloud.SvcMetrics, "memory" | "allocatedMemory"> { | ||
metricsAt: number; | ||
syncId?: string; | ||
} | ||
|
||
const chartConfig = { | ||
value: { | ||
color: "hsl(var(--chart-1))", | ||
label: "Memory Usage", | ||
}, | ||
} satisfies ChartConfig; | ||
|
||
export function LobbyMemoryStats({ | ||
memory, | ||
allocatedMemory, | ||
metricsAt, | ||
syncId, | ||
}: LobbyMemoryStatsProps) { | ||
const data = memory.map((value, i) => ({ | ||
x: `${(memory.length - i) * -15}`, | ||
value, | ||
config: { | ||
label: new Date(metricsAt - (memory.length - i) * timing.seconds(15)), | ||
}, | ||
})); | ||
|
||
const id = useId(); | ||
|
||
const fillId = `fill-${id}`; | ||
return ( | ||
<ChartContainer config={chartConfig}> | ||
<AreaChart accessibilityLayer data={data} syncId={syncId}> | ||
<CartesianGrid vertical={true} /> | ||
<XAxis | ||
interval="preserveStartEnd" | ||
dataKey="x" | ||
hide | ||
axisLine={false} | ||
domain={[0, 60]} | ||
tickCount={60} | ||
includeHidden | ||
/> | ||
<YAxis | ||
dataKey="value" | ||
axisLine={false} | ||
padding={{ top: 10 }} | ||
domain={([, dataMax]) => { | ||
return [0, allocatedMemory || dataMax]; | ||
}} | ||
tickFormatter={(value) => `${filesize(value)}`} | ||
/> | ||
<ChartTooltip | ||
content={ | ||
<ChartTooltipContent | ||
hideIndicator | ||
labelKey="label" | ||
labelFormatter={(label) => { | ||
return format(label, "HH:mm:ss"); | ||
}} | ||
valueFormatter={(value) => { | ||
if (typeof value !== "number") { | ||
return "n/a"; | ||
} | ||
return filesize(value); | ||
}} | ||
/> | ||
} | ||
/> | ||
<defs> | ||
<linearGradient id={fillId} x1="0" y1="0" x2="0" y2="1"> | ||
<stop | ||
offset="5%" | ||
stopColor="var(--color-value)" | ||
stopOpacity={0.8} | ||
/> | ||
<stop | ||
offset="95%" | ||
stopColor="var(--color-value)" | ||
stopOpacity={0.1} | ||
/> | ||
</linearGradient> | ||
</defs> | ||
<Area | ||
isAnimationActive={false} | ||
dataKey="value" | ||
type="linear" | ||
fill={`url(#${fillId})`} | ||
fillOpacity={0.4} | ||
stroke="var(--color-value)" | ||
stackId="a" | ||
/> | ||
</AreaChart> | ||
</ChartContainer> | ||
); | ||
} |
46 changes: 46 additions & 0 deletions
46
apps/hub/src/domains/game/components/game-matchmaker/lobby-metrics.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import type { Rivet } from "@rivet-gg/api"; | ||
import { Flex, Progress, SmallText, WithTooltip } from "@rivet-gg/components"; | ||
import { filesize } from "filesize"; | ||
|
||
interface LobbyMetricsProps extends Rivet.cloud.SvcMetrics { | ||
lobbyId: string; | ||
} | ||
|
||
export function LobbyMetrics({ | ||
allocatedMemory, | ||
memory, | ||
cpu, | ||
}: LobbyMetricsProps) { | ||
const currentMemory = memory[memory.length - 1]; | ||
const memoryPercentage = (currentMemory / (allocatedMemory || 1)) * 100; | ||
|
||
const cpuPercentage = cpu[cpu.length - 1] * 100; | ||
return ( | ||
<Flex gap="2"> | ||
<WithTooltip | ||
trigger={ | ||
<Flex direction="col" gap="2" className="min-w-20"> | ||
<SmallText>Memory</SmallText> | ||
<Progress className="h-2" value={memoryPercentage} /> | ||
</Flex> | ||
} | ||
content={ | ||
<> | ||
{filesize(currentMemory)} / {filesize(allocatedMemory || 1)} ( | ||
{memoryPercentage.toFixed(2)}%) | ||
</> | ||
} | ||
/> | ||
|
||
<WithTooltip | ||
trigger={ | ||
<Flex direction="col" gap="2" className="min-w-20"> | ||
<SmallText>CPU</SmallText> | ||
<Progress className="h-2" value={cpu[cpu.length - 1] * 100} /> | ||
</Flex> | ||
} | ||
content={<>{cpuPercentage.toFixed(2)}%</>} | ||
/> | ||
</Flex> | ||
); | ||
} |
72 changes: 72 additions & 0 deletions
72
apps/hub/src/domains/game/components/game-matchmaker/lobby-stats.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import type { Rivet } from "@rivet-gg/api"; | ||
import { Flex, Progress, ScrollArea, Strong } from "@rivet-gg/components"; | ||
import { filesize } from "filesize"; | ||
import { LobbyCPUStats } from "./lobby-cpu-stats"; | ||
import { LobbyMemoryStats } from "./lobby-memory-stats"; | ||
|
||
interface LobbyStatsProps extends Rivet.cloud.SvcMetrics { | ||
lobbyId: string; | ||
metricsAt: number; | ||
} | ||
|
||
export function LobbyStats({ | ||
cpu, | ||
memory, | ||
metricsAt, | ||
allocatedMemory, | ||
lobbyId, | ||
}: LobbyStatsProps) { | ||
const syncId = `stats-${lobbyId}`; | ||
|
||
const memoryPercentage = | ||
(memory[memory.length - 1] / (allocatedMemory || 1)) * 100; | ||
|
||
const cpuPercentage = cpu[cpu.length - 1]; | ||
|
||
return ( | ||
<ScrollArea className=" h-full w-full overflow-auto p-4"> | ||
<div className="grid grid-cols-1 gap-4 @3xl:grid-cols-2 gap-y-8 "> | ||
<div> | ||
<p className="mb-4 font-bold">Memory Usage</p> | ||
<LobbyMemoryStats | ||
memory={memory} | ||
metricsAt={metricsAt} | ||
allocatedMemory={allocatedMemory} | ||
syncId={syncId} | ||
/> | ||
<Flex items="center" justify="center" py="4" gap="4"> | ||
<Progress value={memoryPercentage} /> | ||
<Flex direction="col" gap="2"> | ||
<Strong className="tabular-nums"> | ||
{memoryPercentage.toFixed(2)}% | ||
</Strong> | ||
</Flex> | ||
</Flex> | ||
<p> | ||
<Strong className="tabular-nums"> | ||
{filesize(memory[memory.length - 1])} | ||
</Strong>{" "} | ||
/{" "} | ||
<span className="tabular-nums"> | ||
{filesize(allocatedMemory || 1)} | ||
</span>{" "} | ||
Total | ||
</p> | ||
</div> | ||
<div> | ||
<p className="mb-4 font-bold">CPU Usage</p> | ||
<LobbyCPUStats cpu={cpu} metricsAt={metricsAt} syncId={syncId} /> | ||
|
||
<Flex items="center" justify="center" py="4" gap="4"> | ||
<Progress value={cpuPercentage} /> | ||
<Flex direction="col" gap="2"> | ||
<Strong className="tabular-nums"> | ||
{cpuPercentage.toFixed(2)}% | ||
</Strong> | ||
</Flex> | ||
</Flex> | ||
</div> | ||
</div> | ||
</ScrollArea> | ||
); | ||
} |
Oops, something went wrong.