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
54 changes: 24 additions & 30 deletions src/components/hooks/useTaskRuns.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import {
Selector,
getGroupVersionKindForModel,
useFlag,
useK8sWatchResource
useK8sWatchResource,
} from '@openshift-console/dynamic-plugin-sdk';
import { differenceBy, uniqBy } from 'lodash-es';
import { uniqBy } from 'lodash-es';
import * as React from 'react';
import {
ApprovalFields,
Expand Down Expand Up @@ -66,7 +66,6 @@ export const useTaskRunsK8s = (

export type UseTaskRunsOptions = {
taskName?: string;
cacheKey?: string;
pipelineRunUid?: string;
pipelineRunFinished?: boolean;
pipelineRunManagedBy?: string;
Expand All @@ -77,8 +76,12 @@ export const useTaskRuns = (
pipelineRunName?: string,
options?: UseTaskRunsOptions,
): [TaskRunKind[], boolean, unknown, GetNextPage, boolean, boolean] => {
const { taskName, cacheKey, pipelineRunUid, pipelineRunFinished, pipelineRunManagedBy } =
options || {};
const {
taskName,
pipelineRunUid,
pipelineRunFinished,
pipelineRunManagedBy,
} = options || {};
const selector: Selector = React.useMemo(() => {
if (pipelineRunName && pipelineRunUid) {
return {
Expand Down Expand Up @@ -110,7 +113,6 @@ export const useTaskRuns = (
selector && {
selector,
},
cacheKey,
pipelineRunFinished,
pipelineRunManagedBy,
);
Expand Down Expand Up @@ -158,15 +160,13 @@ export const useTaskRuns2 = (
selector?: Selector;
limit?: number;
},
cacheKey?: string,
pipelineRunFinished?: boolean,
pipelineRunManagedBy?: string,
): [TaskRunKind[], boolean, unknown, GetNextPage, boolean, boolean] =>
useRuns<TaskRunKind>(
getGroupVersionKindForModel(TaskRunModel),
namespace,
options,
cacheKey,
pipelineRunFinished,
pipelineRunManagedBy,
);
Expand Down Expand Up @@ -209,13 +209,11 @@ export const usePipelineRuns = (
selector?: Selector;
limit?: number;
},
cacheKey?: string,
): [PipelineRunKind[], boolean, unknown, GetNextPage, boolean, boolean] =>
useRuns<PipelineRunKind>(
getGroupVersionKindForModel(PipelineRunModel),
namespace,
options,
cacheKey,
);

export const usePipelineRun = (
Expand Down Expand Up @@ -247,11 +245,11 @@ export const useRuns = <Kind extends K8sResourceKind>(
limit?: number;
name?: string;
},
cacheKey?: string,
pipelineRunFinished?: boolean,
pipelineRunManagedBy?: string,
): [Kind[], boolean, unknown, GetNextPage, boolean, boolean] => {
const etcdRunsRef = React.useRef<Kind[]>([]);
const [trRefreshKey, setTrRefreshKey] = React.useState<string>('');
const optionsMemo = useDeepCompareMemoize(options);
const isTektonResultEnabled = useFlag(FLAG_PIPELINE_TEKTON_RESULT_INSTALLED);
const isList = !optionsMemo?.name;
Expand All @@ -262,7 +260,9 @@ export const useRuns = <Kind extends K8sResourceKind>(
getGroupVersionKindForModel(PipelineRunModel)?.kind;

// Hub cluster detection
const { isResourceManagedByKueue } = useMultiClusterProxyService({ managedBy: pipelineRunManagedBy });
const { isResourceManagedByKueue } = useMultiClusterProxyService({
managedBy: pipelineRunManagedBy,
});
const isTaskRunQuery =
groupVersionKind?.kind === getGroupVersionKindForModel(TaskRunModel)?.kind;

Expand All @@ -271,7 +271,8 @@ export const useRuns = <Kind extends K8sResourceKind>(
optionsMemo?.selector?.matchLabels?.[TektonResourceLabel.pipelinerun];

// Use multi-cluster hook for hub clusters fetching TaskRuns
const shouldUseMultiCluster = isResourceManagedByKueue && isTaskRunQuery && !!pipelineRunName;
const shouldUseMultiCluster =
isResourceManagedByKueue && isTaskRunQuery && !!pipelineRunName;
const [
mcTaskRuns,
mcLoaded,
Expand All @@ -288,7 +289,6 @@ export const useRuns = <Kind extends K8sResourceKind>(
// do not include the limit when querying etcd because result order is not sorted
const watchOptions = React.useMemo(() => {
// reset cached runs as the options have changed
etcdRunsRef.current = [];
return shouldUseMultiCluster
? null
: {
Expand Down Expand Up @@ -329,20 +329,10 @@ export const useRuns = <Kind extends K8sResourceKind>(
const effectiveError = shouldUseMultiCluster ? mcError : error;

const runs = React.useMemo(() => {
if (!etcdRuns) {
if (!etcdRuns || etcdRuns.length === 0) {
return etcdRuns;
}
let value = etcdRunsRef.current
? [
...etcdRuns,
// identify the runs that were removed
...differenceBy(
etcdRunsRef.current,
etcdRuns,
(plr) => plr.metadata.name,
),
]
: [...etcdRuns];
let value = [...etcdRuns];
value.sort((a, b) =>
b.metadata.creationTimestamp.localeCompare(a.metadata.creationTimestamp),
);
Expand All @@ -352,8 +342,12 @@ export const useRuns = <Kind extends K8sResourceKind>(
return value;
}, [etcdRuns, limit]);

// cache the last set to identify removed runs
etcdRunsRef.current = runs;
React.useEffect(() => {
if (etcdRuns.length < etcdRunsRef.current.length) {
setTrRefreshKey((k) => k + 1 + Date.now());
}
etcdRunsRef.current = etcdRuns;
}, [etcdRuns]);

// Query tekton results if there's no limit or we received less items from etcd than the current limit
const queryTr =
Expand Down Expand Up @@ -383,13 +377,13 @@ export const useRuns = <Kind extends K8sResourceKind>(
useTRPipelineRuns(
isPipelineRun ? trNamespace : null,
isPipelineRun ? trOptions : undefined,
isPipelineRun ? cacheKey : undefined,
isPipelineRun ? trRefreshKey : undefined,
);

const [trTRResources, trTRLoaded, trTRError, trTRGetNextPage] = useTRTaskRuns(
!isPipelineRun ? trNamespace : null,
!isPipelineRun ? trOptions : undefined,
!isPipelineRun ? cacheKey : undefined,
!isPipelineRun ? trRefreshKey : undefined,
);

const trResources = (isPipelineRun
Expand Down
69 changes: 27 additions & 42 deletions src/components/hooks/useTektonResult.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,21 +32,13 @@ const useTRRuns = <Kind extends K8sResourceCommon>(
namespace: string,
options?: TektonResultsOptions,
nextPageToken?: string,
cacheKey?: string,
isDevConsoleProxyAvailable?: boolean,
) => Promise<[Kind[], RecordsList, boolean?]>,
) => Promise<[Kind[], RecordsList]>,
namespace: string,
options?: TektonResultsOptions,
cacheKey?: string,
): [Kind[], boolean, unknown, GetNextPage] => {
const isDevConsoleProxyAvailable = useFlag(FLAGS.DEVCONSOLE_PROXY);
const [nextPageToken, setNextPageToken] = React.useState<string>(null);
const [localCacheKey, setLocalCacheKey] = React.useState(cacheKey);

if (cacheKey !== localCacheKey) {
// force update local cache key
setLocalCacheKey(cacheKey);
}

const [result, setResult] = React.useState<
[Kind[], boolean, unknown, GetNextPage]
Expand All @@ -55,7 +47,7 @@ const useTRRuns = <Kind extends K8sResourceCommon>(
// reset token if namespace or options change
React.useEffect(() => {
setNextPageToken(null);
}, [namespace, options, cacheKey]);
}, [namespace, options]);

// eslint-disable-next-line consistent-return
React.useEffect(() => {
Expand All @@ -66,37 +58,32 @@ const useTRRuns = <Kind extends K8sResourceCommon>(
namespace,
options,
nextPageToken,
localCacheKey,
isDevConsoleProxyAvailable,
);
if (!disposed) {
const token = tkPipelineRuns[1].nextPageToken;
const callInflight = !!tkPipelineRuns?.[2];
const loaded = !callInflight;
if (!callInflight) {
setResult((cur) => [
nextPageToken
? [...cur[0], ...tkPipelineRuns[0]]
: tkPipelineRuns[0],
loaded,
undefined,
token
? (() => {
// ensure we can only call this once
let executed = false;
return () => {
if (!disposed && !executed) {
executed = true;
// trigger the update
setNextPageToken(token);
return true;
}
return false;
};
})()
: undefined,
]);
}
setResult((cur) => [
nextPageToken
? [...cur[0], ...tkPipelineRuns[0]]
: tkPipelineRuns[0],
true,
undefined,
token
? (() => {
// ensure we can only call this once
let executed = false;
return () => {
if (!disposed && !executed) {
executed = true;
// trigger the update
setNextPageToken(token);
return true;
}
return false;
};
})()
: undefined,
]);
}
} catch (e) {
if (!disposed) {
Expand All @@ -111,23 +98,21 @@ const useTRRuns = <Kind extends K8sResourceCommon>(
return () => {
disposed = true;
};
}, [namespace, options, nextPageToken, localCacheKey, getRuns]);
}, [namespace, options, nextPageToken, getRuns]);
return result;
};

export const useTRPipelineRuns = (
namespace: string,
options?: TektonResultsOptions,
cacheKey?: string,
): [PipelineRunKind[], boolean, unknown, GetNextPage] =>
useTRRuns<PipelineRunKind>(getPipelineRuns, namespace, options, cacheKey);
useTRRuns<PipelineRunKind>(getPipelineRuns, namespace, options);

export const useTRTaskRuns = (
namespace: string,
options?: TektonResultsOptions,
cacheKey?: string,
): [TaskRunKind[], boolean, unknown, GetNextPage] =>
useTRRuns<TaskRunKind>(getTaskRuns, namespace, options, cacheKey);
useTRRuns<TaskRunKind>(getTaskRuns, namespace, options);

export const useGetPipelineRuns = (
ns: string,
Expand Down
Loading
Loading