Skip to content
Open
Show file tree
Hide file tree
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
35 changes: 17 additions & 18 deletions components/PerformanceList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,35 @@ import { ExplorerTooltip } from "@components/ExplorerTooltip";
import Link from "next/link";
import { useMemo } from "react";
import QRCode from "qrcode.react";
import { useAllScoreData, useEnsData } from "hooks";
import { useEnsData } from "hooks";
import { OrchestratorsQueryResult } from "apollo";
import numeral from "numeral";
import { Pipeline } from "@lib/api/types/get-available-pipelines";
import { Region } from "@lib/api/types/get-regions";
import { AllPerformanceMetrics } from "@lib/api/types/get-performance";

const EmptyData = () => <Skeleton css={{ height: 20, width: 100 }} />;

const PerformanceList = ({
data,
orchestratorIds,
pageSize = 20,
region,
pipeline,
model,
performanceMetrics = null,
isLoadingMetrics = false,
}: {
pageSize: number;
region: Region["id"];
pipeline: Pipeline["id"] | null;
model: string | null;
data: Pick<
performanceMetrics?: AllPerformanceMetrics | null;
isLoadingMetrics?: boolean;
orchestratorIds: Pick<
NonNullable<OrchestratorsQueryResult["data"]>["transcoders"][number],
"id"
>[];
}) => {
const {isValidating, data: allScores} = useAllScoreData(pipeline, model);
const isAIData = pipeline !== null && model !== null;
const scoreAccessor = `scores.${region}`;//total score
const successRateAccessor = `successRates.${region}`;//success rate
Expand All @@ -53,8 +57,8 @@ const PerformanceList = ({
};

const mergedData = useMemo(
() => data.map((o) => ({ ...o, ...allScores?.[o?.id] })),
[allScores, data]
() => orchestratorIds.map((o) => ({ ...o, ...performanceMetrics?.[o?.id] })),
[performanceMetrics, orchestratorIds]
);

//tanstack v7's numberic sorting function incorrectly treats 0, null, and undefined as 0 (the same value).
Expand Down Expand Up @@ -215,11 +219,8 @@ const PerformanceList = ({
defaultCanSort: true,
sortType: sortTypeFn,
Cell: ({ value }) => {
if (
isValidating
) {
return <EmptyData />;
}
if (isLoadingMetrics) return <EmptyData />;

return (
<Box>
{typeof value === "undefined" || value === null ?
Expand Down Expand Up @@ -251,9 +252,8 @@ const PerformanceList = ({
accessor: `${successRateAccessor}`,
sortType: sortTypeFn,
Cell: ({ value }) => {
if (isValidating) {
return <EmptyData />;
}
if (isLoadingMetrics) return <EmptyData />;

return (
<Box>
{typeof value === "undefined" || value === null ?
Expand Down Expand Up @@ -286,9 +286,8 @@ const PerformanceList = ({
accessor: `${roundTripScoreAccessor}`,
sortType: sortTypeFn,
Cell: ({ value }) => {
if (isValidating) {
return <EmptyData />;
}
if (isLoadingMetrics) return <EmptyData />;

return (
<Box>
{typeof value === "undefined" || value === null ?
Expand All @@ -302,7 +301,7 @@ const PerformanceList = ({
},
},
],
[region, isValidating]
[region, isLoadingMetrics]
);
return (
<Table data={mergedData} columns={columns} initialState={initialState} />
Expand Down
42 changes: 36 additions & 6 deletions pages/leaderboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import { EnsIdentity } from "@lib/api/types/get-ens";
import { Box, Container, Flex, Heading } from "@livepeer/design-system";
import { ChevronDownIcon } from "@modulz/radix-icons";
import Head from "next/head";
import { useState } from "react";
import { useState, useMemo } from "react";
import { getApollo, OrchestratorsQueryResult } from "../apollo";
import { Pipeline } from "@lib/api/types/get-available-pipelines";
import { useRegionsData } from "hooks/useSwr";
import { useRegionsData, useAllScoreData } from "hooks/useSwr";
import { Region } from "@lib/api/types/get-regions";

type PageProps = {
Expand All @@ -25,6 +25,36 @@ const LeaderboardPage = ({ orchestratorIds }: PageProps) => {
const [selectedModel, setSelectedModel] = useState<string | null>(null);
const knownRegions = useRegionsData();
const [region, setRegion] = useState<Region["id"]>("GLOBAL");
const { data: allScores, isValidating } = useAllScoreData(selectedPipeline, selectedModel);

// Filter regions to only show those with data.
const availableRegions = useMemo(() => {
if (!knownRegions?.regions) return [];

const pipelineType = selectedPipeline ? "ai" : "transcoding";

// If no scores loaded yet, just filter by pipeline type.
if (!allScores) {
return knownRegions.regions.filter((r) => r.type === pipelineType);
}

// Collect regions that have score data.
const regionsWithData = new Set<string>();
Object.values(allScores).forEach((orchestratorData) => {
if (orchestratorData?.scores) {
Object.entries(orchestratorData.scores).forEach(([regionKey, value]) => {
if (value != null) {
regionsWithData.add(regionKey);
}
});
}
});

// Filter regions based on pipeline type and data availability.
return knownRegions.regions.filter(
(r) => r.type === pipelineType && regionsWithData.has(r.id)
);
}, [knownRegions?.regions, allScores, selectedPipeline]);

return (
<>
Expand Down Expand Up @@ -99,9 +129,7 @@ const LeaderboardPage = ({ orchestratorIds }: PageProps) => {
appearance: "none",
}}
>
{knownRegions?.regions
.filter((r) => r.type === (selectedPipeline?"ai":"transcoding"))
.map((region) => {
{availableRegions.map((region) => {
return (<Box as="option" key={region.id} value={region.id}>
{region.name}
</Box>)
Expand Down Expand Up @@ -137,11 +165,13 @@ const LeaderboardPage = ({ orchestratorIds }: PageProps) => {
</Flex>
<Box css={{ mb: "$5" }}>
<PerformanceList
data={orchestratorIds}
orchestratorIds={orchestratorIds}
pageSize={20}
region={region}
pipeline={selectedPipeline}
model={selectedModel}
performanceMetrics={allScores}
isLoadingMetrics={isValidating}
/>
</Box>
</Flex>
Expand Down