vitess.io/vitess@v0.16.2/web/vtadmin/src/util/workflows.ts (about) 1 /** 2 * Copyright 2021 The Vitess Authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 import { vtctldata, vtadmin as pb } from '../proto/vtadmin'; 17 import { formatAlias } from './tablets'; 18 19 /** 20 * getStreams returns a flat list of streams across all keyspaces/shards in the workflow. 21 */ 22 export const getStreams = <W extends pb.IWorkflow>(workflow: W | null | undefined): vtctldata.Workflow.IStream[] => { 23 if (!workflow) { 24 return []; 25 } 26 27 return Object.values(workflow.workflow?.shard_streams || {}).reduce((acc, shardStream) => { 28 (shardStream.streams || []).forEach((stream) => { 29 acc.push(stream); 30 }); 31 return acc; 32 }, [] as vtctldata.Workflow.IStream[]); 33 }; 34 35 /** 36 * getStream returns the stream in the workflow with the given streamKey. 37 */ 38 export const getStream = <W extends pb.IWorkflow>( 39 workflow: W | null | undefined, 40 streamKey: string | null | undefined 41 ): vtctldata.Workflow.IStream | undefined => { 42 if (!streamKey || !workflow) { 43 return undefined; 44 } 45 46 return getStreams(workflow).find((s) => formatStreamKey(s) === streamKey); 47 }; 48 49 export const formatStreamKey = <S extends vtctldata.Workflow.IStream>(stream: S | null | undefined): string | null => { 50 return stream?.tablet && stream?.id ? `${formatAlias(stream.tablet)}/${stream.id}` : null; 51 }; 52 53 export const getStreamSource = <S extends vtctldata.Workflow.IStream>(stream: S | null | undefined): string | null => { 54 return stream?.binlog_source?.keyspace && stream?.binlog_source.shard 55 ? `${stream.binlog_source.keyspace}/${stream.binlog_source.shard}` 56 : null; 57 }; 58 59 export const getStreamTarget = <S extends vtctldata.Workflow.IStream>( 60 stream: S | null | undefined, 61 workflowKeyspace: string | null | undefined 62 ): string | null => { 63 return stream?.shard && workflowKeyspace ? `${workflowKeyspace}/${stream.shard}` : null; 64 }; 65 66 /** 67 * getTimeUpdated returns the `time_updated` timestamp of the most recently 68 * updated stream in the workflow. 69 */ 70 export const getTimeUpdated = <W extends pb.IWorkflow>(workflow: W | null | undefined): number => { 71 // Note: long-term it may be better to get this from the `vreplication_log` data 72 // added by https://github.com/vitessio/vitess/pull/7831 73 const timestamps = getStreams(workflow).map((s) => parseInt(`${s.time_updated?.seconds}`, 10)); 74 return Math.max(...timestamps); 75 }; 76 77 /** 78 * getStreamTablets returns an unordered set of tablet alias strings across all streams 79 * in the workflow. 80 */ 81 export const getStreamTablets = <W extends pb.IWorkflow>(workflow: W | null | undefined): string[] => { 82 const streams = getStreams(workflow); 83 if (!Array.isArray(streams)) { 84 return []; 85 } 86 87 const aliases = new Set<string>(); 88 streams.forEach((stream) => { 89 const alias = formatAlias(stream.tablet); 90 if (alias) { 91 aliases.add(alias); 92 } 93 }); 94 95 return [...aliases]; 96 };