Skip to content

Commit 5705948

Browse files
authored
Merge pull request #354 from ethpandaops/fix/timings
fix: exec timings
2 parents e8efe6c + 427fc7e commit 5705948

File tree

5 files changed

+118
-46
lines changed

5 files changed

+118
-46
lines changed

src/pages/ethereum/execution/timings/IndexPage.tsx

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ import type { TimeRange } from './IndexPage.types';
2020
* Displays CL-EL communication timing data for engine_newPayload and engine_getBlobs API calls
2121
*/
2222
export function IndexPage(): JSX.Element {
23-
// Time range state - default to last 24 hours for hourly aggregated data
24-
const [timeRange, setTimeRange] = useState<TimeRange>('day');
23+
// Time range state - default to last 1 hour
24+
const [timeRange, setTimeRange] = useState<TimeRange>('1hour');
2525

2626
// Reference nodes filter - default to true (only ethPandaOps controlled fleet)
2727
const [referenceNodesOnly, setReferenceNodesOnly] = useState(true);
@@ -35,8 +35,15 @@ export function IndexPage(): JSX.Element {
3535
{ id: 'getBlobs', anchors: ['blob-duration'] },
3636
]);
3737

38-
// Fetch all engine timing data
39-
const { data, isLoading, error } = useEngineTimingsData({ timeRange, referenceNodesOnly });
38+
// Map tab index to tab name
39+
const activeTab = selectedIndex === 0 ? 'newPayload' : 'getBlobs';
40+
41+
// Fetch engine timing data (getBlobs queries only run when that tab is visited)
42+
const { data, isLoading, isLoadingBlobs, error } = useEngineTimingsData({
43+
timeRange,
44+
referenceNodesOnly,
45+
activeTab,
46+
});
4047

4148
// Loading state
4249
if (isLoading) {
@@ -92,7 +99,7 @@ export function IndexPage(): JSX.Element {
9299
<div className="mb-6 flex items-center gap-4">
93100
<span className="text-sm font-medium text-muted">Time Range:</span>
94101
<div className="flex gap-2">
95-
{(['hour', 'day', '7days'] as const).map(range => (
102+
{(['1hour', '3hours', '6hours'] as const).map(range => (
96103
<button
97104
key={range}
98105
onClick={() => setTimeRange(range)}
@@ -102,7 +109,7 @@ export function IndexPage(): JSX.Element {
102109
: 'bg-surface text-muted hover:bg-surface/80 hover:text-foreground'
103110
}`}
104111
>
105-
{range === 'hour' ? 'Last Hour' : range === 'day' ? 'Last 24h' : 'Last 7 Days'}
112+
{range === '1hour' ? 'Last 1h' : range === '3hours' ? 'Last 3h' : 'Last 6h'}
106113
</button>
107114
))}
108115
</div>
@@ -212,12 +219,12 @@ export function IndexPage(): JSX.Element {
212219
<TabPanels className="mt-6">
213220
{/* newPayload Tab */}
214221
<TabPanel>
215-
<NewPayloadTab data={data} timeRange={timeRange} />
222+
<NewPayloadTab data={data} />
216223
</TabPanel>
217224

218225
{/* getBlobs Tab */}
219226
<TabPanel>
220-
<GetBlobsTab data={data} timeRange={timeRange} />
227+
<GetBlobsTab data={data} isLoading={isLoadingBlobs} />
221228
</TabPanel>
222229
</TabPanels>
223230
</TabGroup>

src/pages/ethereum/execution/timings/IndexPage.types.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { z } from 'zod';
33
/**
44
* Time range options for engine timing data
55
*/
6-
export type TimeRange = 'hour' | 'day' | '7days';
6+
export type TimeRange = '1hour' | '3hours' | '6hours';
77

88
/**
99
* Tab identifiers for the timings page
@@ -19,7 +19,7 @@ export const timingsSearchSchema = z.object({
1919
tab: z.enum(['overview', 'newPayload', 'getBlobs', 'clients']).optional(),
2020

2121
// Time range for data queries
22-
range: z.enum(['hour', 'day', '7days']).optional(),
22+
range: z.enum(['1hour', '3hours', '6hours']).optional(),
2323

2424
// Filter to reference nodes only (ethPandaOps controlled fleet)
2525
refNodes: z.boolean().optional(),
@@ -33,7 +33,7 @@ export type TimingsSearch = z.infer<typeof timingsSearchSchema>;
3333
/**
3434
* Default time range for the page
3535
*/
36-
export const DEFAULT_TIME_RANGE: TimeRange = 'day';
36+
export const DEFAULT_TIME_RANGE: TimeRange = '1hour';
3737

3838
/**
3939
* Status values for engine_newPayload responses

src/pages/ethereum/execution/timings/components/GetBlobsTab/GetBlobsTab.tsx

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,77 @@ import { Card } from '@/components/Layout/Card';
33
import { Stats } from '@/components/DataDisplay/Stats';
44
import { MultiLineChart } from '@/components/Charts/MultiLine';
55
import { BarChart } from '@/components/Charts/Bar';
6+
import { LoadingContainer } from '@/components/Layout/LoadingContainer';
67
import { useThemeColors } from '@/hooks/useThemeColors';
78
import { formatSlot } from '@/utils';
89
import type { EngineTimingsData } from '../../hooks/useEngineTimingsData';
9-
import type { TimeRange } from '../../IndexPage.types';
1010
import { ClientVersionBreakdown } from '../ClientVersionBreakdown';
1111

1212
export interface GetBlobsTabProps {
1313
data: EngineTimingsData;
14-
timeRange: TimeRange;
14+
isLoading?: boolean;
15+
}
16+
17+
/**
18+
* Loading skeleton for the getBlobs tab
19+
*/
20+
function GetBlobsTabSkeleton(): JSX.Element {
21+
return (
22+
<div className="space-y-6">
23+
{/* Stats skeleton */}
24+
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4">
25+
{Array.from({ length: 4 }).map((_, index) => (
26+
<Card key={index}>
27+
<div className="space-y-2 p-4">
28+
<LoadingContainer className="h-3 w-20 rounded-xs" />
29+
<LoadingContainer className="h-8 w-24 rounded-xs" />
30+
</div>
31+
</Card>
32+
))}
33+
</div>
34+
35+
{/* Client breakdown skeleton */}
36+
<Card>
37+
<div className="space-y-4 p-4">
38+
<LoadingContainer className="h-5 w-40 rounded-xs" />
39+
<LoadingContainer className="h-48 w-full rounded-xs" />
40+
</div>
41+
</Card>
42+
43+
{/* Charts skeleton */}
44+
<div className="grid grid-cols-1 gap-6 lg:grid-cols-2">
45+
{Array.from({ length: 2 }).map((_, index) => (
46+
<Card key={index}>
47+
<div className="space-y-4 p-4">
48+
<LoadingContainer className="h-5 w-32 rounded-xs" />
49+
<LoadingContainer className="h-[375px] w-full rounded-xs" />
50+
</div>
51+
</Card>
52+
))}
53+
</div>
54+
</div>
55+
);
1556
}
1657

1758
/**
1859
* GetBlobs tab showing detailed engine_getBlobs timing analysis
1960
*/
20-
export function GetBlobsTab({ data, timeRange }: GetBlobsTabProps): JSX.Element {
61+
export function GetBlobsTab({ data, isLoading }: GetBlobsTabProps): JSX.Element {
2162
const themeColors = useThemeColors();
63+
64+
// Show skeleton while loading
65+
if (isLoading) {
66+
return <GetBlobsTabSkeleton />;
67+
}
68+
2269
const { getBlobsBySlot, getBlobsByElClient, getBlobsDurationHistogram, getBlobsHourly, getBlobsDaily } = data;
2370

2471
// Filter to SUCCESS status only for duration-based charts
2572
const successBlobsByElClient = getBlobsByElClient.filter(r => r.status?.toUpperCase() === 'SUCCESS');
2673

2774
// Determine which aggregated data source to use based on time range
28-
const useHourlyData = timeRange === 'hour' || timeRange === 'day';
75+
// Always use hourly data since all time ranges are < 24 hours
76+
const useHourlyData = true;
2977

3078
// Calculate summary stats from pre-aggregated hourly/daily data
3179
const aggregatedStats = (() => {

src/pages/ethereum/execution/timings/components/NewPayloadTab/NewPayloadTab.tsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,16 @@ import { ScatterAndLineChart } from '@/components/Charts/ScatterAndLine';
99
import { useThemeColors } from '@/hooks/useThemeColors';
1010
import { formatSlot } from '@/utils';
1111
import type { EngineTimingsData } from '../../hooks/useEngineTimingsData';
12-
import type { TimeRange } from '../../IndexPage.types';
1312
import { ClientVersionBreakdown } from '../ClientVersionBreakdown';
1413

1514
export interface NewPayloadTabProps {
1615
data: EngineTimingsData;
17-
timeRange: TimeRange;
1816
}
1917

2018
/**
2119
* NewPayload tab showing detailed engine_newPayload timing analysis
2220
*/
23-
export function NewPayloadTab({ data, timeRange }: NewPayloadTabProps): JSX.Element {
21+
export function NewPayloadTab({ data }: NewPayloadTabProps): JSX.Element {
2422
const themeColors = useThemeColors();
2523
const { newPayloadBySlot, newPayloadDurationHistogram, newPayloadByElClient } = data;
2624

@@ -31,8 +29,8 @@ export function NewPayloadTab({ data, timeRange }: NewPayloadTabProps): JSX.Elem
3129
const [visibleScatterSeries, setVisibleScatterSeries] = useState<Set<string>>(new Set());
3230
const [scatterSeriesInitialized, setScatterSeriesInitialized] = useState(false);
3331

34-
// Determine which aggregated data source to use based on time range
35-
const useHourlyData = timeRange === 'hour' || timeRange === 'day';
32+
// Always use hourly data since all time ranges are < 24 hours
33+
const useHourlyData = true;
3634
const { newPayloadHourly, newPayloadDaily } = data;
3735

3836
// Calculate summary stats from pre-aggregated hourly/daily data

0 commit comments

Comments
 (0)