From 8166377b5a3b6648fa395b6ad86e1c9ded3c1222 Mon Sep 17 00:00:00 2001 From: Ashique Ansari Date: Tue, 11 Jul 2023 22:57:51 +0530 Subject: [PATCH] Improve performance of showing partial Pipelines and runs --- frontend/src/api/pipelines/custom.ts | 14 ++++++++++++-- .../apiHooks/usePipelineRunsForPipeline.ts | 7 ++++--- frontend/src/concepts/pipelines/const.ts | 2 ++ .../content/tables/pipeline/PipelinesTable.tsx | 1 - .../tables/pipeline/PipelinesTableExpandedRow.tsx | 7 +++++-- .../content/tables/pipeline/PipelinesTableRow.tsx | 3 ++- .../tables/pipeline/expandedRowRenderUtils.tsx | 3 +-- .../src/concepts/pipelines/content/tables/utils.ts | 5 +---- frontend/src/concepts/pipelines/types.ts | 1 + .../screens/detail/pipelines/PipelinesList.tsx | 9 ++++----- 10 files changed, 32 insertions(+), 20 deletions(-) diff --git a/frontend/src/api/pipelines/custom.ts b/frontend/src/api/pipelines/custom.ts index 2a704a2a41..de7a913174 100644 --- a/frontend/src/api/pipelines/custom.ts +++ b/frontend/src/api/pipelines/custom.ts @@ -64,7 +64,13 @@ export const listExperiments: ListExperimentsAPI = (hostPath) => (opts) => export const listPipelines: ListPipelinesAPI = (hostPath) => (opts, count) => handlePipelineFailures( // eslint-disable-next-line camelcase - proxyGET(hostPath, '/apis/v1beta1/pipelines', { page_size: count }, opts), + proxyGET( + hostPath, + '/apis/v1beta1/pipelines', + // eslint-disable-next-line camelcase + { page_size: count, sort_by: 'created_at desc' }, + opts, + ), ); export const listPipelineRuns: ListPipelinesRunAPI = (hostPath) => (opts) => @@ -77,7 +83,7 @@ export const listPipelineRunJobs: ListPipelinesRunJobAPI = (hostPath) => (opts) handlePipelineFailures(proxyGET(hostPath, '/apis/v1beta1/jobs', {}, opts)); export const listPipelineRunsByPipeline: ListPipelineRunsByPipelineAPI = - (hostPath) => (opts, pipelineId) => + (hostPath) => (opts, pipelineId, count) => handlePipelineFailures( proxyGET( hostPath, @@ -85,6 +91,10 @@ export const listPipelineRunsByPipeline: ListPipelineRunsByPipelineAPI = { 'resource_reference_key.id': pipelineId, 'resource_reference_key.type': ResourceTypeKF.PIPELINE_VERSION, + // eslint-disable-next-line camelcase + page_size: count, + // eslint-disable-next-line camelcase + sort_by: 'created_at desc', }, opts, ), diff --git a/frontend/src/concepts/pipelines/apiHooks/usePipelineRunsForPipeline.ts b/frontend/src/concepts/pipelines/apiHooks/usePipelineRunsForPipeline.ts index b915241ebf..3155a2fc79 100644 --- a/frontend/src/concepts/pipelines/apiHooks/usePipelineRunsForPipeline.ts +++ b/frontend/src/concepts/pipelines/apiHooks/usePipelineRunsForPipeline.ts @@ -4,13 +4,14 @@ import useFetchState, { FetchStateCallbackPromise } from '~/utilities/useFetchSt import { usePipelinesAPI } from '~/concepts/pipelines/context'; import { POLL_INTERVAL } from '~/utilities/const'; -const usePipelineRunsForPipeline = (pipeline: PipelineKF) => { +const usePipelineRunsForPipeline = (pipeline: PipelineKF, limit: number) => { const { api } = usePipelinesAPI(); const pipelineId = pipeline.id; const call = React.useCallback>( - (opts) => api.listPipelineRunsByPipeline(opts, pipelineId).then(({ runs }) => runs ?? []), - [api, pipelineId], + (opts) => + api.listPipelineRunsByPipeline(opts, pipelineId, limit).then(({ runs }) => runs ?? []), + [api, pipelineId, limit], ); return useFetchState(call, [], { refreshRate: POLL_INTERVAL }); diff --git a/frontend/src/concepts/pipelines/const.ts b/frontend/src/concepts/pipelines/const.ts index 706b4a2dfa..353146946d 100644 --- a/frontend/src/concepts/pipelines/const.ts +++ b/frontend/src/concepts/pipelines/const.ts @@ -1,2 +1,4 @@ export const PIPELINE_ROUTE_NAME = 'ds-pipeline-pipelines-definition'; export const PIPELINE_DEFINITION_NAME = 'pipelines-definition'; +export const TABLE_CONTENT_LIMIT = 5; +export const LIMIT_MAX_ITEM_COUNT = TABLE_CONTENT_LIMIT + 1; diff --git a/frontend/src/concepts/pipelines/content/tables/pipeline/PipelinesTable.tsx b/frontend/src/concepts/pipelines/content/tables/pipeline/PipelinesTable.tsx index 38153c3421..0a542c771d 100644 --- a/frontend/src/concepts/pipelines/content/tables/pipeline/PipelinesTable.tsx +++ b/frontend/src/concepts/pipelines/content/tables/pipeline/PipelinesTable.tsx @@ -32,7 +32,6 @@ const PipelinesTable: React.FC = ({ {...tableProps} data={pipelines} columns={pipelineColumns} - defaultSortColumn={1} variant={TableVariant.compact} truncateRenderingAt={contentLimit} rowRenderer={(pipeline, rowIndex) => ( diff --git a/frontend/src/concepts/pipelines/content/tables/pipeline/PipelinesTableExpandedRow.tsx b/frontend/src/concepts/pipelines/content/tables/pipeline/PipelinesTableExpandedRow.tsx index 3f9babe266..7b93fdeb78 100644 --- a/frontend/src/concepts/pipelines/content/tables/pipeline/PipelinesTableExpandedRow.tsx +++ b/frontend/src/concepts/pipelines/content/tables/pipeline/PipelinesTableExpandedRow.tsx @@ -13,6 +13,7 @@ import { PipelineKF, PipelineRunKF } from '~/concepts/pipelines/kfTypes'; import IndentSection from '~/pages/projects/components/IndentSection'; import { FetchState } from '~/utilities/useFetchState'; import { usePipelinesAPI } from '~/concepts/pipelines/context'; +import { TABLE_CONTENT_LIMIT } from '~/concepts/pipelines/const'; import { RenderContentList, combineRunsByColumn } from './expandedRowRenderUtils'; type PipelinesTableExpandedRowProps = { @@ -75,7 +76,7 @@ const PipelinesTableExpandedRow: React.FC = ({ ); } - const renderContentByColumn = combineRunsByColumn(runs, 5); + const renderContentByColumn = combineRunsByColumn(runs, TABLE_CONTENT_LIMIT); return ( @@ -92,7 +93,9 @@ const PipelinesTableExpandedRow: React.FC = ({ } items={[ ...renderContentByColumn.names, - runs.length > 5 && View all runs, + runs.length > TABLE_CONTENT_LIMIT && ( + View all runs + ), ]} /> diff --git a/frontend/src/concepts/pipelines/content/tables/pipeline/PipelinesTableRow.tsx b/frontend/src/concepts/pipelines/content/tables/pipeline/PipelinesTableRow.tsx index f029ee40b1..1ad301a8b3 100644 --- a/frontend/src/concepts/pipelines/content/tables/pipeline/PipelinesTableRow.tsx +++ b/frontend/src/concepts/pipelines/content/tables/pipeline/PipelinesTableRow.tsx @@ -16,6 +16,7 @@ import { RunNameForPipeline, RunStatus, } from '~/concepts/pipelines/content/tables/renderUtils'; +import { LIMIT_MAX_ITEM_COUNT } from '~/concepts/pipelines/const'; type PipelinesTableRowProps = { pipeline: PipelineKF; @@ -32,7 +33,7 @@ const PipelinesTableRow: React.FC = ({ }) => { const navigate = useNavigate(); const { namespace } = usePipelinesAPI(); - const runsFetchState = usePipelineRunsForPipeline(pipeline); + const runsFetchState = usePipelineRunsForPipeline(pipeline, LIMIT_MAX_ITEM_COUNT); const [isExpanded, setExpanded] = React.useState(false); const createdDate = new Date(pipeline.created_at); diff --git a/frontend/src/concepts/pipelines/content/tables/pipeline/expandedRowRenderUtils.tsx b/frontend/src/concepts/pipelines/content/tables/pipeline/expandedRowRenderUtils.tsx index 08ab343ce0..ba0adc9706 100644 --- a/frontend/src/concepts/pipelines/content/tables/pipeline/expandedRowRenderUtils.tsx +++ b/frontend/src/concepts/pipelines/content/tables/pipeline/expandedRowRenderUtils.tsx @@ -7,7 +7,6 @@ import { RunNameForPipeline, RunStatus, } from '~/concepts/pipelines/content/tables/renderUtils'; -import { sortRunsByCreated } from '~/concepts/pipelines/content/tables/utils'; type RenderContentListProps = { firstItem?: React.ReactNode; @@ -30,7 +29,7 @@ type RenderContentByColumn = { }; export const combineRunsByColumn = (runs: PipelineRunKF[], sliceCount?: number) => - sortRunsByCreated(runs).reduce( + runs.reduce( (acc, run, i) => { if (sliceCount && i >= sliceCount) { return acc; diff --git a/frontend/src/concepts/pipelines/content/tables/utils.ts b/frontend/src/concepts/pipelines/content/tables/utils.ts index fbee2882d3..5d41d0d7ea 100644 --- a/frontend/src/concepts/pipelines/content/tables/utils.ts +++ b/frontend/src/concepts/pipelines/content/tables/utils.ts @@ -8,10 +8,7 @@ import { } from '~/concepts/pipelines/kfTypes'; import { DateRangeString, splitDateRange } from '~/components/dateRange/utils'; -export const sortRunsByCreated = (runs: PipelineRunKF[]) => - [...runs].sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime()); - -export const getLastRun = (runs: PipelineRunKF[]) => sortRunsByCreated(runs)[0]; +export const getLastRun = (runs: PipelineRunKF[]) => runs[0]; export const getRunDuration = (run: PipelineRunKF): number => { const finishedDate = new Date(run.finished_at); diff --git a/frontend/src/concepts/pipelines/types.ts b/frontend/src/concepts/pipelines/types.ts index 21f36ff152..a46b9cd9ea 100644 --- a/frontend/src/concepts/pipelines/types.ts +++ b/frontend/src/concepts/pipelines/types.ts @@ -49,6 +49,7 @@ export type ListPipelineRunJobs = (opts: K8sAPIOptions) => Promise Promise; export type ListPipelineTemplates = ( opts: K8sAPIOptions, diff --git a/frontend/src/pages/projects/screens/detail/pipelines/PipelinesList.tsx b/frontend/src/pages/projects/screens/detail/pipelines/PipelinesList.tsx index cd709c04c6..f038c0d882 100644 --- a/frontend/src/pages/projects/screens/detail/pipelines/PipelinesList.tsx +++ b/frontend/src/pages/projects/screens/detail/pipelines/PipelinesList.tsx @@ -7,12 +7,11 @@ import usePipelines from '~/concepts/pipelines/apiHooks/usePipelines'; import IndentSection from '~/pages/projects/components/IndentSection'; import { usePipelinesAPI } from '~/concepts/pipelines/context'; import EmptyStateErrorMessage from '~/components/EmptyStateErrorMessage'; - -const CONTENT_LIMIT = 5; +import { TABLE_CONTENT_LIMIT, LIMIT_MAX_ITEM_COUNT } from '~/concepts/pipelines/const'; const PipelinesList: React.FC = () => { const { namespace } = usePipelinesAPI(); - const [pipelines, loaded, loadError, refresh] = usePipelines(); + const [pipelines, loaded, loadError, refresh] = usePipelines(LIMIT_MAX_ITEM_COUNT); const navigate = useNavigate(); if (loadError) { @@ -40,12 +39,12 @@ const PipelinesList: React.FC = () => { `/projects/${namespace}/pipeline/view/${id}`} refreshPipelines={refresh} /> - {pipelines.length > CONTENT_LIMIT && ( + {pipelines.length > TABLE_CONTENT_LIMIT && (