go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/analysis/frontend/ui/src/tools/progress_tools.ts (about) 1 // Copyright 2022 The LUCI Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 import dayjs, { extend as dayjsextend } from 'dayjs'; 16 import isSameOrAfter from 'dayjs/plugin/isSameOrAfter'; 17 18 import { 19 ClusteringVersion, 20 GetReclusteringProgressRequest, 21 ReclusteringProgress, 22 } from '@/proto/go.chromium.org/luci/analysis/proto/v1/clusters.pb'; 23 import { getClustersService } from '@/services/services'; 24 25 dayjsextend(isSameOrAfter); 26 27 export const fetchProgress = async (project: string): Promise<ReclusteringProgress> => { 28 const clustersService = getClustersService(); 29 const request: GetReclusteringProgressRequest = { 30 name: `projects/${encodeURIComponent(project)}/reclusteringProgress`, 31 }; 32 const response = await clustersService.getReclusteringProgress(request); 33 return response; 34 }; 35 36 export const progressNotYetStarted = -1; 37 export const noProgressToShow = -2; 38 39 export const progressToLatestAlgorithms = (progress: ReclusteringProgress): number => { 40 return progressTo(progress, (target: ClusteringVersion) => { 41 // 'next' will be set on all progress objects. 42 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion 43 return target.algorithmsVersion >= progress.next!.algorithmsVersion; 44 }); 45 }; 46 47 export const progressToLatestConfig = (progress: ReclusteringProgress): number => { 48 // 'next' will be set on all progress objects. 49 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion 50 const targetConfigVersion = dayjs(progress.next!.configVersion); 51 return progressTo(progress, (target: ClusteringVersion) => { 52 return dayjs(target.configVersion).isSameOrAfter(targetConfigVersion); 53 }); 54 }; 55 56 export const progressToRulesVersion = (progress: ReclusteringProgress, rulesVersion: string): number => { 57 const ruleDate = dayjs(rulesVersion); 58 return progressTo(progress, (target: ClusteringVersion) => { 59 return dayjs(target.rulesVersion).isSameOrAfter(ruleDate); 60 }); 61 }; 62 63 // progressTo returns the progress to completing a re-clustering run 64 // satisfying the given re-clustering target, expressed as a predicate. 65 // If re-clustering to a goal that would satisfy the target has started, 66 // the returned value is value from 0 to 1000. If the run is pending, 67 // the value -1 is returned. 68 const progressTo = (progress: ReclusteringProgress, predicate: (target: ClusteringVersion) => boolean): number => { 69 // 'last' will be set on all progress objects. 70 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion 71 if (predicate(progress.last!)) { 72 // Completed 73 return 1000; 74 } 75 76 // 'next' will be set on all progress objects. 77 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion 78 if (predicate(progress.next!)) { 79 return progress.progressPerMille || 0; 80 } 81 // Run not yet started (e.g. because we are still finishing a previous 82 // re-clustering). 83 return progressNotYetStarted; 84 };