Skip to content

Commit af687b3

Browse files
feat: startup snapshot writing card
1 parent e755f55 commit af687b3

9 files changed

Lines changed: 245 additions & 186 deletions

File tree

src/api/entities.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ export const tileTypeSchema = z.enum([
8585
"snapld",
8686
"snapdc",
8787
"snapin",
88+
"snapwr",
8889

8990
// shred tiles
9091
"netlnk",
@@ -338,6 +339,15 @@ export const bootProgressSchema = z.object({
338339
.nullable()
339340
.optional(),
340341
loading_full_snapshot_insert_accounts: z.number().nullable().optional(),
342+
loading_full_snapshot_snapwr_in_bytes_decompressed: z.coerce
343+
.number()
344+
.nullable()
345+
.optional(),
346+
loading_full_snapshot_snapwr_out_bytes_decompressed: z.coerce
347+
.number()
348+
.nullable()
349+
.optional(),
350+
loading_full_snapshot_snapwr_accounts: z.number().nullable().optional(),
341351

342352
loading_incremental_snapshot_elapsed_seconds: z
343353
.number()
@@ -370,6 +380,20 @@ export const bootProgressSchema = z.object({
370380
.number()
371381
.nullable()
372382
.optional(),
383+
loading_incremental_snapshot_snapwr_in_bytes_decompressed: z.coerce
384+
.number()
385+
.nullable()
386+
.optional(),
387+
loading_incremental_snapshot_snapwr_out_bytes_decompressed: z.coerce
388+
.number()
389+
.nullable()
390+
.optional(),
391+
loading_incremental_snapshot_snapwr_accounts: z
392+
.number()
393+
.nullable()
394+
.optional(),
395+
396+
accounts_database_path: z.string().nullable().optional(),
373397

374398
wait_for_supermajority_bank_hash: z.string().nullable().optional(),
375399
wait_for_supermajority_shred_version: z.string().nullable().optional(),

src/features/Overview/SlotPerformance/atoms.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ export const groupedLiveIdlePerTileAtom = atom((get) => {
133133
export const snapshotTimerIndicesAtom = atom(
134134
(get): [TileType, number[]][] | undefined => {
135135
const tiles = get(tilesAtom);
136-
const tileTypes: TileType[] = ["snapld", "snapdc", "snapin"];
136+
const tileTypes: TileType[] = ["snapld", "snapdc", "snapin", "snapwr"];
137137

138138
if (!tiles) return;
139139

src/features/StartupProgress/Firedancer/Snapshot/SnapshotBarsCard.tsx

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,35 +5,39 @@ import { Bars } from "../Bars";
55
import { useValuePerSecond } from "../useValuePerSecond";
66
import { bootProgressPhaseAtom } from "../../atoms";
77
import { useAtomValue } from "jotai";
8-
import { useEffect, useMemo } from "react";
8+
import { memo, useEffect, useMemo } from "react";
99
import StorageIcon from "@material-design-icons/svg/filled/storage.svg?react";
1010
import { compactSingleDecimalFormatter } from "../../../../numUtils";
1111
import type { FormattedBytes } from "../../../../utils";
1212

13+
const gap = "4px";
14+
1315
interface SnapshotBarsCardProps {
16+
title: string;
1417
headerContent: JSX.Element;
1518
footer?: JSX.Element;
1619
throughput: number | null | undefined;
17-
containerClassName: string;
1820
maxThroughput: number;
1921
}
2022
export function SnapshotBarsCard({
23+
title,
2124
headerContent,
2225
footer,
2326
throughput,
24-
containerClassName,
2527
maxThroughput,
2628
}: SnapshotBarsCardProps) {
2729
return (
28-
<Card className={clsx(styles.card, styles.barsCard, containerClassName)}>
30+
<Card className={clsx(styles.card, styles.barsCard)}>
2931
<Flex
3032
justify="between"
31-
align="center"
32-
wrap="wrap"
33-
gapX="4"
33+
wrap="nowrap"
34+
gap={gap}
3435
className={styles.cardHeader}
3536
>
36-
{headerContent}
37+
<SnapshotTitle text={title} />
38+
<Flex gap={gap} minWidth="0" className={styles.headerRightSection}>
39+
{headerContent}
40+
</Flex>
3741
</Flex>
3842

3943
<Bars value={throughput ?? 0} max={maxThroughput} />
@@ -53,21 +57,16 @@ function ValueUnitText({
5357
return (
5458
<>
5559
<Text>{value ?? "--"}</Text>
56-
{unit && (
57-
<>
58-
{" "}
59-
<Text className={styles.secondaryColor}>{unit}</Text>
60-
</>
61-
)}
60+
{unit && <Text className={styles.secondaryColor}> {unit}</Text>}
6261
</>
6362
);
6463
}
6564

6665
interface SnapshotTitleProps {
6766
text: string;
6867
}
69-
export function SnapshotTitle({ text }: SnapshotTitleProps) {
70-
return <Text className={clsx(styles.title, styles.ellipsis)}>{text}</Text>;
68+
function SnapshotTitle({ text }: SnapshotTitleProps) {
69+
return <Text className={clsx(styles.leftColumn, styles.title)}>{text}</Text>;
7170
}
7271

7372
interface AccountsRateProps {
@@ -94,7 +93,7 @@ export function AccountsRate({ cumulativeAccounts }: AccountsRateProps) {
9493
}, [accountsPerSecond, cumulativeAccounts]);
9594

9695
return (
97-
<div className={styles.accountsRate}>
96+
<div className={styles.rightColumn}>
9897
<ValueUnitText value={value} unit="Accounts / sec" />
9998
</div>
10099
);
@@ -109,13 +108,13 @@ export function SnapshotTotalComplete({
109108
total,
110109
}: SnapshotTotalCompleteProps) {
111110
return (
112-
<div className={styles.total}>
111+
<Flex className={styles.centerColumn}>
113112
<ValueUnitText value={completed?.value} unit={completed?.unit} />
114113

115114
<Text> / </Text>
116115

117116
<ValueUnitText value={total?.value} unit={total?.unit} />
118-
</div>
117+
</Flex>
119118
);
120119
}
121120

@@ -128,27 +127,30 @@ export function SnapshotThroughput({
128127
throughput,
129128
}: SnapshotThroughputProps) {
130129
return (
131-
<div className={clsx(styles.throughput, { [styles.withPrefix]: !!prefix })}>
130+
<div className={styles.rightColumn}>
132131
{prefix && <Text className={styles.secondaryColor}>{prefix} </Text>}
133132
<ValueUnitText value={throughput?.value} unit={throughput?.unit} />
134133
<Text className={styles.secondaryColor}>/sec</Text>
135134
</div>
136135
);
137136
}
138137

139-
interface SnapshotReadPathProps {
140-
readPath?: string | null;
138+
interface SnapshotPathProps {
139+
path?: string | null;
141140
}
142-
export function SnapshotReadPath({ readPath }: SnapshotReadPathProps) {
141+
export const MSnapshotPath = memo(function SnapshotPath({
142+
path,
143+
}: SnapshotPathProps) {
144+
if (!path) return;
143145
return (
144146
<Flex
145147
align="center"
146148
gap="10px"
147149
wrap="nowrap"
148-
className={styles.readPathContainer}
150+
className={styles.pathContainer}
149151
>
150152
<StorageIcon />
151-
<Text className={clsx(styles.readPath, styles.ellipsis)}>{readPath}</Text>
153+
<Text className={clsx(styles.path, styles.ellipsis)}>{path}</Text>
152154
</Flex>
153155
);
154-
}
156+
});

src/features/StartupProgress/Firedancer/Snapshot/SnapshotDecompressingCard.tsx

Lines changed: 6 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,9 @@ import { useEffect } from "react";
44
import {
55
SnapshotBarsCard,
66
SnapshotThroughput,
7-
SnapshotTitle,
87
SnapshotTotalComplete,
98
} from "./SnapshotBarsCard";
10-
import { Flex } from "@radix-ui/themes";
119
import { formatBytes } from "../../../../utils";
12-
import styles from "./snapshot.module.css";
1310
import { useEma } from "../../../../hooks/useEma";
1411

1512
interface SnapshotDecompressingCardProps {
@@ -36,10 +33,6 @@ export function SnapshotDecompressingCard({
3633
resetDecompressed();
3734
}, [phase, resetCompressed, resetDecompressed]);
3835

39-
const compressedThroughputObj =
40-
compressedThroughput == null
41-
? undefined
42-
: formatBytes(compressedThroughput);
4336
const decompressedThroughputObj =
4437
decompressedThroughput == null
4538
? undefined
@@ -52,33 +45,14 @@ export function SnapshotDecompressingCard({
5245

5346
return (
5447
<SnapshotBarsCard
55-
containerClassName={styles.decompressingCard}
48+
title="Decompressing"
5649
headerContent={
5750
<>
58-
<Flex
59-
flexGrow="1"
60-
justify="between"
61-
align="center"
62-
className={styles.decompressingCardLeft}
63-
>
64-
<SnapshotTitle text="Decompressing" />
65-
<SnapshotTotalComplete completed={completedObj} total={totalObj} />
66-
</Flex>
67-
<Flex
68-
gapX="30px"
69-
justify="end"
70-
flexGrow="1"
71-
className={styles.decompressingCardRight}
72-
>
73-
<SnapshotThroughput
74-
prefix="Input"
75-
throughput={compressedThroughputObj}
76-
/>
77-
<SnapshotThroughput
78-
prefix="Output"
79-
throughput={decompressedThroughputObj}
80-
/>
81-
</Flex>
51+
<SnapshotTotalComplete completed={completedObj} total={totalObj} />
52+
<SnapshotThroughput
53+
prefix="Output"
54+
throughput={decompressedThroughputObj}
55+
/>
8256
</>
8357
}
8458
throughput={compressedThroughput}

src/features/StartupProgress/Firedancer/Snapshot/SnapshotInsertingCard.tsx

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
import {
22
AccountsRate,
33
SnapshotBarsCard,
4-
SnapshotThroughput,
5-
SnapshotTitle,
64
SnapshotTotalComplete,
75
} from "./SnapshotBarsCard";
86
import { formatBytes } from "../../../../utils";
9-
import styles from "./snapshot.module.css";
107

118
interface SnapshotInsertingCardProps {
129
decompressedThroughput?: number;
@@ -20,26 +17,19 @@ export function SnapshotInsertingCard({
2017
decompressedTotal,
2118
cumulativeAccounts,
2219
}: SnapshotInsertingCardProps) {
23-
const throughputObj =
24-
decompressedThroughput == null
25-
? undefined
26-
: formatBytes(decompressedThroughput);
2720
const completedObj =
2821
decompressedCompleted == null
2922
? undefined
3023
: formatBytes(decompressedCompleted);
3124
const totalObj =
3225
decompressedTotal == null ? undefined : formatBytes(decompressedTotal);
33-
3426
return (
3527
<SnapshotBarsCard
36-
containerClassName={styles.insertingCard}
28+
title="Inserting"
3729
headerContent={
3830
<>
39-
<SnapshotTitle text="Inserting" />
40-
<AccountsRate cumulativeAccounts={cumulativeAccounts} />
4131
<SnapshotTotalComplete completed={completedObj} total={totalObj} />
42-
<SnapshotThroughput throughput={throughputObj} />
32+
<AccountsRate cumulativeAccounts={cumulativeAccounts} />
4333
</>
4434
}
4535
throughput={decompressedThroughput}

src/features/StartupProgress/Firedancer/Snapshot/SnapshotReadingCard.tsx

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,24 @@
11
import { bootProgressPhaseAtom } from "../../atoms";
22
import { useAtomValue } from "jotai";
3-
import { useEffect, useMemo } from "react";
3+
import { useEffect } from "react";
44
import {
55
SnapshotBarsCard,
6-
SnapshotReadPath,
6+
MSnapshotPath,
77
SnapshotThroughput,
8-
SnapshotTitle,
98
SnapshotTotalComplete,
109
} from "./SnapshotBarsCard";
1110
import { formatBytes } from "../../../../utils";
12-
import styles from "./snapshot.module.css";
1311
import { useEma } from "../../../../hooks/useEma";
1412

1513
interface SnapshotReadingCardProps {
1614
compressedCompleted?: number | null;
1715
compressedTotal?: number | null;
18-
readPath?: string | null;
16+
path?: string | null;
1917
}
2018
export function SnapshotReadingCard({
2119
compressedCompleted: completed,
2220
compressedTotal: total,
23-
readPath,
21+
path,
2422
}: SnapshotReadingCardProps) {
2523
const phase = useAtomValue(bootProgressPhaseAtom);
2624
const { ema: throughput, reset } = useEma(completed);
@@ -35,21 +33,16 @@ export function SnapshotReadingCard({
3533
const completedObj = completed == null ? undefined : formatBytes(completed);
3634
const totalObj = total == null ? undefined : formatBytes(total);
3735

38-
const footer = useMemo(() => {
39-
return <SnapshotReadPath readPath={readPath} />;
40-
}, [readPath]);
41-
4236
return (
4337
<SnapshotBarsCard
44-
containerClassName={styles.readingCard}
38+
title="Reading"
4539
headerContent={
4640
<>
47-
<SnapshotTitle text="Reading" />
4841
<SnapshotTotalComplete completed={completedObj} total={totalObj} />
4942
<SnapshotThroughput throughput={throughputObj} />
5043
</>
5144
}
52-
footer={footer}
45+
footer={<MSnapshotPath path={path} />}
5346
throughput={throughput}
5447
maxThroughput={800_000_000}
5548
/>
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import {
2+
SnapshotBarsCard,
3+
MSnapshotPath,
4+
SnapshotThroughput,
5+
SnapshotTotalComplete,
6+
} from "./SnapshotBarsCard";
7+
import { formatBytes } from "../../../../utils";
8+
9+
interface SnapshotWritingCardProps {
10+
decompressedThroughput?: number;
11+
decompressedCompleted?: number | null;
12+
decompressedTotal?: number | null;
13+
path?: string | null;
14+
}
15+
export function SnapshotWritingCard({
16+
decompressedThroughput,
17+
decompressedCompleted,
18+
decompressedTotal,
19+
path,
20+
}: SnapshotWritingCardProps) {
21+
const throughputObj =
22+
decompressedThroughput == null
23+
? undefined
24+
: formatBytes(decompressedThroughput);
25+
const completedObj =
26+
decompressedCompleted == null
27+
? undefined
28+
: formatBytes(decompressedCompleted);
29+
const totalObj =
30+
decompressedTotal == null ? undefined : formatBytes(decompressedTotal);
31+
32+
return (
33+
<SnapshotBarsCard
34+
title="Writing"
35+
headerContent={
36+
<>
37+
<SnapshotTotalComplete completed={completedObj} total={totalObj} />
38+
<SnapshotThroughput prefix="Writing" throughput={throughputObj} />
39+
</>
40+
}
41+
footer={<MSnapshotPath path={path} />}
42+
throughput={decompressedThroughput}
43+
maxThroughput={3_500_000_000}
44+
/>
45+
);
46+
}

0 commit comments

Comments
 (0)